У меня есть огромная грамматика ANTLR, и я столкнулся с проблемой с ее маленьким кусочком. Грамматика имеет два правила выраж и наборы, как определено ниже:Неопределенность преемственности в ANTLR 4
expr:
id
|(PLUS|MINUS|MULTIPLY|AND|NEGATION)expr
| expr (MULTIPLY |DIVIDE| MODULO)
| expr (PLUS | MINUS) expr
;
set:
EMPTY
| MULTIPLY set
| set PLUS set
| UNION '(' set (COMMA set)* ')'
| INTER '(' set (COMMA set)* ')'
| expr
;
Проблема здесь состоит в том, что для набора формы * s1 + * s2 должна быть уменьшена в следующем:
set -> set PLUS set
, а затем каждый из множества в RHS должны сводиться к:
set -> MULTIPLY set
set -> expr
term -> id
Но вместо этого они уменьшают как:
set -> MULTIPLY set
set -> expr
expr -> expr PLUS expr
Из-за чего набор forn *s1 +*s2
разобран как *(s1 + *s2)
вместо (*s1) + (*s2)
.
Одно из правил набора, сводит его к выражению. Существует много других аналогичных правил в грамматике, которые сводятся к expr. Проблема возникает здесь, потому что некоторые из правил в set и expr аналогичны. Но поскольку некоторые правила разные, я не могу объединить их вместе.
В наборе, даже если приоритет правила MULTIPLY set
выше set PLUS set
, набор уменьшается на MUTIPLY set
правило.
Есть ли способ исправить эту проблему?
EDIT:
Добавление рабочий пример:
Грамматика:
grammar T;
expr
: ID
| (PLUS | MINUS | MULTIPLY | AND | NEGATION) expr
| expr (MULTIPLY | DIVIDE | MODULO)
| expr (PLUS | MINUS) expr
;
set:
EMPTY
| MULTIPLY set
| set PLUS set
| UNION '(' set (COMMA set)* ')'
| INTER '(' set (COMMA set)* ')'
| expr
;
ID : [a-zA-Z] [a-zA-Z0-9]*;
PLUS : '+';
MINUS : '-';
MULTIPLY : '*';
AND : '&&';
NEGATION : '!';
DIVIDE : '/';
MODULO : '%';
COMMA : ',';
EMPTY: '\\empty';
UNION: '\\union';
INTER: '\\inter';
SPACES : [ \t\r\n] -> skip;
код для его выполнения:
TLexer lexer = new TLexer(new ANTLRInputStream("*s1 + *s2"));
TParser parser = new TParser(new CommonTokenStream(lexer));
RuleContext tree = parser.set();
tree.inspect(parser);
Выход он генерировал:
set
/\
* set
|
expr
/| \
/| \
expr + expr
| /\
s1 * expr
|
s2
Можете ли вы предоставить [SSCCE] (http://sscce.org/), так как я не мог воспроизвести его? (см. мой ответ) –
@BartKiers, я добавил рабочий пример. Извините, что раньше не приводил пример. – user2888308