antlr анализатор жадный? - PullRequest
0 голосов
/ 19 января 2019

Я не понимаю, почему эта грамматика 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.

где вина в моих рассуждениях?

1 Ответ

0 голосов
/ 19 января 2019

грамматики будут пытаться сначала найти соответствие этому правилу

Это так.Тем не менее, вы сделали унарный минус более низким приоритетом, чем бинарный плюс.

Это означает, что выражение интерпретируется как -((5+9)+1000) вместо (-(5+9))+1000.

...