ANTLR предупреждает множественные альтернативы, как это понять и как от этого избавиться?

Другие эксперты ANTLR, не могли бы вы объяснить, почему это предупреждение появляется в ANTLWorks? Как понять это сообщение и как избавиться от него в данном конкретном случае?

Пример правильного ввода: abc "xyz def" abc следует распознавать как токен keywordExpr, а "xyz def" - как фразу Expr.

[14:32:24] предупреждение (200): TestExpr.g:12:4: решение может соответствовать входным данным, таким как "CHAR", используя несколько альтернатив: 1, 2

В результате альтернатива (ы) 2 были отключены для этого ввода [14:32:24] предупреждение (200): / Users / imochurad /Development/antlr3/Grammars/TestExpr.g:12:4: решение может соответствовать такому вводу в качестве "CHAR" используется несколько альтернатив: 1, 2

В результате альтернатива (ы) 2 были отключены для этого ввода

grammar TestExpr;

options {
output=AST;
    ASTLabelType=CommonTree; 
}

expr
    :   kpExpr*;
kpExpr  :   keywordExpr|phraseExpr; 
keywordExpr
    :   CHAR+;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
phraseExpr
    :   '"' CHAR+ (' ' CHAR+)* '"';
CHAR    :   ('A'..'Z') | ('a'..'z');
INT :   '0'..'9'+;
NEWLINE :   '\r'? '\n';
WS  :   (' '|'\t'|'\n'|'\r')+ {skip();};

Большое спасибо!

1 ответ

Как написано, ваша грамматика неоднозначна при разборе строк без кавычек. ABC может быть проанализирован как один keywordExpr (abc) или три (a, b и c) или даже два. Я думаю, вы ожидаете, что ключевые слова будут разделены пробелами. Однако, поскольку вы пропускаете пробелы в лексере, парсер не может определить разницу между abc а также a b c,

Я подозреваю что keywordExpr а также phraseExpr Должны быть правила лексера:

KeywordExpr: CHAR+;
PhraseExpr:  '"' CHAR+ (' ' CHAR+)* '"';

CHAR должно также стать фрагментом, чтобы случайно не генерировать CHAR маркер, когда у вас есть одно ключевое слово.

С этим изменением abc становится недвусмысленным в лексере, так как лексер будет использовать максимально возможное совпадение.

Относительно того, чтобы пробелы обрабатывались по-разному, это работает лучше всего, если это делается в лексере. Приведенное выше правило для PhraseExpr будет правильно обрабатывать пробел, поскольку, когда лексер встречает его, он не может соответствовать WS править. Обработка в парсере намного сложнее.

Другие вопросы по тегам