我正在尝试了解antlr4的特性,并通过参考代码和书籍,我对Java中的"表达式"规则有一个问题。g4 (https://raw.githubusercontent.com/antlr/grammars-v4/master/java/Java.g4)和该书(2012年第2版,第73页):
-
根据这本书,'+'的优先级低于'^',因此'+'规则低于'^'规则。但是Java代码是相反的
-
根据这本书,'^'规则有关联=权利。但是Java代码没有,除了'^='和类似的规则。
书和代码哪个是对的?
顺便说一句,代码和书之间还有另一个区别。在代码中,assoc=right位于规则的开头,而在书中,它位于操作符之后,但看起来语法被更改了(代码适用于4.5.3),因此必须更新这本书。
下面是相关的Java代码。G4代码片段:
expression
: primary
| expression ('*'|'/'|'%') expression
| expression ('+'|'-') expression
| expression '^' expression
// this indicates that precedence is: * > + > ^
// BUT it SHOULD be: ^ > * > +
// and both + and ^ are assoc=left
// BUT it SHOULD be: LEFT for + and RIGHT for ^
| <assoc=right> expression
( '='
| '+='
| '^='
)
expression
;
注意:在上面的问题中,我假设^表示取幂,但正如答案所指出的,在java中^具有不同的含义。
说明
正确答案在Java语言规范中。我们将关注当前的规范Java SE 8。
在语言描述中,我们感兴趣的是关于二元操作符表达式的三个小节(15.2表达式的形式)。描述越早的操作符,其优先级就越高。
15.18 Additive Operators (page 563)
操作符+和-称为加性操作符。
然后我们读到:
加性操作符具有相同的优先级,并且在语法上左结合(它们从左到右分组)。
15.22位运算符和逻辑运算符(第575页)
位操作符和逻辑操作符包括与操作符& 排他或操作符^和包容或操作符|。
然后我们读到:
每一个操作符在语法上左结合(每一组从左到右)
15.26赋值操作符(page 588)
赋值操作符有:
= *= /= %= += -= <<= >>= >>>= &= ^= |=
共有12个赋值操作符;
允许链式赋值。
结论在Java 8中,加性加运算符+
比独占或运算符^
具有更高的优先级。XOR ^
算子和加性加算子+
为左结合算子。赋值操作符的右结合性(例如^=
)允许链式赋值。
Java。g4您粘贴的代码片段是正确的