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 的第一个替代项中,以便 * 可以是后缀一元运算符或二元运算符。

令我惊讶的是,这似乎打破了二元运算符优先级的逻辑:

这是一个错误,还是这种行为是预期的?我如何获得我希望的行为?

不确定这是否是预期的行为...但是,像这样更具可读性的语法似乎可以满足您的预期(并保留优先级):

expr:   expr '*' expr #MulExpr
    |   expr '+' expr #Addxpr
    |   expr '*'      #PointerExpr
    |   '(' expr ')'  #NestedExpr
    |   INT           #IntExpr
    |   ID            #IdExpr
    ;

每个备选方案后的#...Expr都叫labels