antlr 解析器是贪心的吗?

is antlr parser greedy?

我不明白为什么这个antlr4语法

grammar antmath1;

expr
    :   '(' expr ')'                         # parensExpr
    |   op=('+'|'-') expr                    # unaryExpr
    |   left=expr op=('*'|'/') right=expr    # infixExpr
    |   left=expr op=('+'|'-') right=expr    # infixExpr
    |   value=NUM                            # numberExpr
    ;

NUM :   [0-9]+;
WS  :   [ \t\r\n] -> channel(HIDDEN);

工作正常: antlr tree produced by -(5+9)+1000; result=986

但为什么是这个:

grammar antmath;

expr
    :   '(' expr ')'                         # parensExpr
    |   left=expr op=('*'|'/') right=expr    # infixExpr
    |   left=expr op=('+'|'-') right=expr    # infixExpr
    |   op=('+'|'-') expr                    # unaryExpr
    |   value=NUM                            # numberExpr
    ;

NUM :   [0-9]+;
WS  :   [ \t\r\n] -> channel(HIDDEN);

失败: antlr tree produced by the same expression; result=-1014

我希望第一个语法 1(输出正确的结果)产生与语法 2(错误的输出)相同的结果。这背后的原因:唯一允许“-”作为第一个标记的规则是#unaryExpr,因此任何语法生成的解析器都会首先尝试匹配该规则。然后,假设解析器是贪婪的(对于两种语法中的任何一种),我希望它把“(5+9)+1000”作为一个整体并将其与 expr 匹配,因为它是一个有效的 expr。

我的推理哪里错了?

the grammars would try to match that rule first

确实如此。但是,您已经使一元减号的优先级低于二进制加号。

这意味着表达式被解释为 -((5+9)+1000) 而不是 (-(5+9))+1000