Я не понимаю, почему эта грамматика 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, полученное из - (5 + 9) +1000; результат = 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, созданное тем же выражением; результат = -1014
Я ожидаю, что первая грамматика1 (которая выводит правильный результат) даст тот же результат, что и грамматика2 (неправильный вывод). Причина этого заключается в том, что единственное правило, которое допускает использование символа «-» в качестве первого токена, - это #unaryExpr, поэтому анализатор, сгенерированный любой из грамматик, сначала попытается сопоставить это правило. Затем, если синтаксический анализатор является жадным (для любой из двух грамматик), я ожидал бы, что он возьмет «(5 + 9) +1000» в целом и сопоставит его с expr, что он делает, потому что это допустимый expr.
где вина в моих рассуждениях?