ANTLR 运算符优先级被可选的右递归破坏了吗?
ANTLR operator precedence broken by optional right recursion?
我对这个语法的行为感到困惑(在 ANTLR 4.8 中):
grammar Bug;
stat: expr ';' ;
expr: expr '*' expr?
| expr '+' expr
| '(' expr ')'
| INT
| ID
;
ID : [a-zA-Z]+ ;
INT : [0-9]+ ;
WS : [ \t\n\r]+ -> skip ;
这是对书中示例的最小修改;我所做的就是将 ?
添加到 expr
的第一个替代项中,以便 *
可以是后缀一元运算符或二元运算符。
令我惊讶的是,这似乎打破了二元运算符优先级的逻辑:
- 没有
?
,3*4+5;
解析为 (stat (expr (expr (expr 3) * (expr 4)) + (expr 5)) ;)
(如预期)
- 与
?
、3*4+5;
解析为 (stat (expr (expr 3) * (expr (expr 4) + (expr 5))) ;)
(wat?)
这是一个错误,还是这种行为是预期的?我如何获得我希望的行为?
不确定这是否是预期的行为...但是,像这样更具可读性的语法似乎可以满足您的预期(并保留优先级):
expr: expr '*' expr #MulExpr
| expr '+' expr #Addxpr
| expr '*' #PointerExpr
| '(' expr ')' #NestedExpr
| INT #IntExpr
| ID #IdExpr
;
每个备选方案后的#...Expr
都叫labels。
我对这个语法的行为感到困惑(在 ANTLR 4.8 中):
grammar Bug;
stat: expr ';' ;
expr: expr '*' expr?
| expr '+' expr
| '(' expr ')'
| INT
| ID
;
ID : [a-zA-Z]+ ;
INT : [0-9]+ ;
WS : [ \t\n\r]+ -> skip ;
这是对书中示例的最小修改;我所做的就是将 ?
添加到 expr
的第一个替代项中,以便 *
可以是后缀一元运算符或二元运算符。
令我惊讶的是,这似乎打破了二元运算符优先级的逻辑:
- 没有
?
,3*4+5;
解析为(stat (expr (expr (expr 3) * (expr 4)) + (expr 5)) ;)
(如预期) - 与
?
、3*4+5;
解析为(stat (expr (expr 3) * (expr (expr 4) + (expr 5))) ;)
(wat?)
这是一个错误,还是这种行为是预期的?我如何获得我希望的行为?
不确定这是否是预期的行为...但是,像这样更具可读性的语法似乎可以满足您的预期(并保留优先级):
expr: expr '*' expr #MulExpr
| expr '+' expr #Addxpr
| expr '*' #PointerExpr
| '(' expr ')' #NestedExpr
| INT #IntExpr
| ID #IdExpr
;
每个备选方案后的#...Expr
都叫labels。