ANTLR4 отличается приоритетом в двух, казалось бы, эквивалентных грамматиках - PullRequest
0 голосов
/ 03 июля 2019

Следующие тестовые грамматики отличаются только тем, что первая альтернатива правила 'expr' либо указана inline, либо ссылается на другое правило 'notExpression' с тем же самым определением. Но эта грамматика производит различные деревья, разбирающие это: '! а & б '. Почему?

Я действительно хочу, чтобы грамматика производила первый результат (с НЕ связанным с идентификатором, а не с выражением AND), но мне все еще нужно иметь 'expr' для ссылки на 'notExpression' в моей реальной грамматике. Что я должен изменить?

grammar test;
s: expr ';' <EOF>;
expr:
    NOT expr
    | left=expr AND right=expr
    | identifier
    ;
identifier: LETTER (LETTER)*;
WS  :  ' '+ ->skip;
NOT: '!';
AND: '&';
LETTER: 'A'..'z';

Дерево одно

grammar test;
s: expr ';' <EOF>;
expr:
    notExpression
    | left=expr AND right=expr
    | identifier
    ;
notExpression:  NOT expr;
identifier: LETTER (LETTER)*;
WS  :  ' '+ ->skip;
NOT: '!';
AND: '&';
LETTER: 'A'..'z';

Дерево два

1 Ответ

0 голосов
/ 03 июля 2019

Я как бы получил ответ на вторую часть моего вопроса, которая все еще не совсем удовлетворяет меня, потому что использование этого подхода в реальной сложной грамматике будет уродливым.Что касается первой части (ПОЧЕМУ), я до сих пор не знаю, так что больше ответов приветствуются.

В любом случае, чтобы исправить приоритет при наличии ссылочного правила, правило «notExpression» можно изменить следующим образом:

notExpression:  NOT (identifier|expr);

, который производит дерево, отличное от обоих, показанных в исходном вопросе, но, по крайней мере, НЕ приобретает более высокий приоритет. Разобрать дерево

...