ANTLR ошибка нескольких альтернатив - PullRequest
1 голос
/ 06 ноября 2011

Когда я пытаюсь выполнить грамматику ANTLR, я получаю следующее исключение:

Решение может соответствовать вводу, такому как "DIGIT..LETTER", используя несколько альтернатив: 1, 2

Моя грамматика выглядит так:

grammar twp3;
ALPHA   : ('a'..'z'|'A'..'Z'); 
DIGIT :  ('0' .. '9');
LETTER  : ALPHA | '_';
identifier  :   LETTER ( LETTER | DIGIT )*;
number  :  DIGIT+;
type    :   primitiveType  | identifier |('any' 'defined' 'by' identifier);
primitiveType   :   'int' | 'string' | 'binary' | 'any';
typedef :   structdef | sequencedef | uniondef | forwarddef;
field   :   'optional'? type identifier ';';

Проблема заключается в многократном использовании идентификатора по типу и полю.

Пожалуйста, помогите мне исправить мою грамматику.

Спасибо.

1 Ответ

3 голосов
/ 07 ноября 2011

Допустим, вы пытаетесь проанализировать ввод "abc" (без кавычек).Теперь ваше правило field содержит type identifier, и type также может соответствовать identifier.Таким образом, вы могли бы сказать, что парсер должен соответствовать identifier identifier.Но как вход должен быть «разделен»?Синтаксический анализатор может сопоставить "a" с первым identifier и "bc" со вторым identifier.Но он также может соответствовать "ab" первому и "c" второму.

Тот факт, что синтаксический анализатор может создать более одного разбора из одного входа, является неоднозначностьюв вашей грамматике (сообщение об ошибке вы столкнулись).И причина этого в том, что вы пытаетесь создать идентификаторы во время анализа, в то время как вы должны создавать их во время лексера.Итак, если вы создаете токены лексера identifier вместо токенов парсера, все должно быть в порядке.

И ваш лексер не должен создавать токены ALPHA, DIGIT и LETTER.Эти правила должны использоваться только другим лексером (поэтому они должны быть помечены как «фрагментированные» правила).

Наконец, точно так же, как правило идентификатора, вы должны сделать правило number правилом лексера вместоправило синтаксического анализатора (правила лексера начинаются с заглавной буквы, правила синтаксического анализатора с строчной буквы):

grammar twp3;

type          : primitiveType  | Identifier | 'any' 'defined' 'by' Identifier;
primitiveType : 'int' | 'string' | 'binary' | 'any';
field         : 'optional'? type Identifier ';';

Identifier : LETTER (LETTER | DIGIT)*;
Number     : DIGIT+;

fragment ALPHA  : ('a'..'z'|'A'..'Z'); 
fragment DIGIT  : ('0' .. '9');
fragment LETTER : ALPHA | '_';
...