antlr не анализирует, когда в токене упоминается только один другой токен

Я пытаюсь выучить грамматики EBNF с помощью ANTLR. Поэтому я решил преобразовать грамматику EBNF из Википедии в ANTLR 4 и поиграть с ней. Однако у меня было ужасное время на этом. Я смог сократить грамматику до одного шага, который порождает проблему.

Кажется, если у меня есть ссылка на один токен только на другой токен, тогда ANTLR 4 не сможет проанализировать ввод.

Вот моя грамматика:

grammar Hello;
program  : statement+ ; 
statement : IDENTIFIER STATEMENTEND /*| LETTERS STATEMENTEND */ ;
LETTERS : [a-z]+ ;
IDENTIFIER : LETTERS ;
SEMICOLON : [;] ; 
STATEMENTEND : SEMICOLON NEWLINE* | NEWLINE+ ; 
fragment NEWLINE : '\r' '\n' | '\n' | '\r';

Примечание IDENTIFIER относится только к LETTERS.

Если я предоставлю этот ввод:

a;

Затем я получаю эту ошибку:

line 1:0 mismatched input 'a' expecting IDENTIFIER
(program a ;\n)

Однако, если я раскомментирую код и предоставлю тот же ввод, я получу законный вывод:

(program (statement a ;\n))

Я не понимаю, почему один работает, а другой нет.


person dodtsair    schedule 13.05.2013    source источник


Ответы (1)


Токену a будет назначен только один тип токена. Поскольку этот входной текст соответствует правилам LETTERS и IDENTIFIER, ANTLR 4 назначит тип в соответствии с первым правилом, появившимся в лексере, что означает, что вход a будет токеном типа LETTERS.

Если вы хотели, чтобы LETTERS было только частью других правил лексера, а не формировало сами токены LETTERS, вы можете объявить его как правило fragment.

fragment LETTERS : [a-z]+;
IDENTIFIER : LETTERS;

В этом случае a будет назначен тип токена IDENTIFIER и будет работать исходное правило парсера.

person Sam Harwell    schedule 13.05.2013
comment
Ах, это имеет гораздо больше смысла. У вас есть ссылка на документацию antlr4, которая охватывает это? - person dodtsair; 14.05.2013