【问题标题】:Describing operator precedence using EBNF使用 EBNF 描述运算符优先级
【发布时间】:2014-08-07 14:53:08
【问题描述】:

我已经为我计划在以后的项目中使用的预处理器语言编写了标记器和表达式评估器。我开始想也许我应该用 EBNF(扩展巴科斯-瑙尔形式)来描述这种语言,以使语法更易于维护,甚至可以用它来生成更高版本的解析器。

我的第一印象是 EBNF 用于标记化过程和语法验证。后来我发现它也可以用来描述运算符优先级,如in this postWikipedia article

expression ::= equality-expression
equality-expression ::= additive-expression ( ( '==' | '!=' ) additive-expression ) *
additive-expression ::= multiplicative-expression ( ( '+' | '-' ) multiplicative-expression ) *
multiplicative-expression ::= primary ( ( '*' | '/' ) primary ) *
primary ::= '(' expression ')' | NUMBER | VARIABLE | '-' primary

我可以看到生成器如何生成内置运算符优先级的代码,但这真的应该如何表达优先级吗?运算符优先级不是更多关于语义,而 EBNF 不是关于语法吗?如果我决定在 EBNF 中编写我的语言描述,我应该在编写时考虑运算符优先级还是在单独的部分中记录?

【问题讨论】:

  • 没有。运算符优先级不是语义的,它是关于语法和分组的,它是在解析时实现的,而不是随后实现的。没有理由不在 EBNF 中表达它。
  • 好问题。正是我现在正在努力解决的问题。

标签: programming-languages language-design operator-precedence ebnf expression-evaluation


【解决方案1】:

为我的大学学位做了类似的事情。

我建议不要使用运算符优先级功能,即使看起来更容易像“语法糖”。

为什么?因为大部分用EBNF来描述的语言,都使用了很多不同特性的操作符,用EBNF表达式来更好地描述和更新,而不是操作符优先级。

有些运算符是一元前缀,有些是一元后缀,有些是二进制(也称为“中缀”),一些二进制是从左到右计算的,还有一些是从右到左计算的。一些符号在某些上下文中是运算符,并用作其他标记,在其他上下文中,例如“+”、“-”,可以是二元运算符(“x - y”)、一元前缀运算符(“x - -y” ),或文字的一部分(“x + -5”)。

根据我的经验,用 EBNF 表达式来描述它们更“安全”。除非您描述的编程语言非常小,语法运算符很少且相似(例如:全二进制,或全前缀一元)。

只要我的 2 美分。

【讨论】:

  • 我建议在词法分析时对字面符号进行分类。这样,我们在句法分析中只需要考虑一元和二元运算符。当不使用后缀一元运算符时,生活也变得更加轻松。对于没有后缀一元的强大语言来说,Rust 是一个很好的例子。如果它更容易解析 - 它很可能更容易被人眼阅读。
猜你喜欢
  • 2015-08-29
  • 2011-07-07
  • 2011-06-21
  • 2013-02-24
  • 2012-08-10
  • 2020-03-05
  • 2012-12-13
相关资源
最近更新 更多