2013-07-18 2 views
0

Я новичок в antlr. Я хочу написать грамматику для разбора ниже входа:ANTLR4: несоответствующий ввод

commit a1b2c3d4 

Грамматика приведен ниже ::

grammar commit; 

file : 'commit' COMMITHASH NEWLINE; 

COMMITHASH : [a-z0-9]+; 
DATE  : ~[\r\n]+; 
NEWLINE : '\r'?'\n'; 

При попытке разбора выше входных данных, используя грамматику, он бросает исключение ниже: :

линия 1: 0 несовпадающими ввода 'фиксации a1b2c3d4' ожидая 'совершить'

Примечание: я намеренно добавлен трет он токен DATE. Без токена DATE он отлично работает. Но я хотел бы знать, что происходит, когда добавлен токен DATE.

Я ссылался на ссылку Antlr4: Mismatched input, но я еще не понял, что произошло.

ответ

2

ANTLR lexers полностью назначают однозначные типы токенов до того, как парсер когда-либо используется. Если одно правило lexer может соответствовать более символам, чем другое правило lexer, правило, соответствующее более символам, всегда предпочтительнее ANTLR, независимо от порядка, в котором правила лексера отображаются в грамматике. Когда два или более правила соответствуют точно такой же длине входных символов (и никакое другое правило не совпадает с этим количеством входных символов), для правила, которое появляется первым в грамматике, назначается тип токена.

Ваш лексер содержит правило DATE, которое соответствует всем символам, кроме символа новой строки. Так как это всегда совпадает весь текст строки, и ни один из ваших маркеров не занимать несколько строк, то результат будет следующим:

  • Если весь текст в одной строке соответствует commit неназванный маркер, соответствующий этому входу будет создана последовательность.
  • Если весь текст одной строки соответствует [a-z0-9]+, то для всего текста строки будет создан токен COMMITHASH. DATE также соответствует этому входу, но COMMITHASH появляется первым, поэтому он используется.
  • В противном случае, если одна строка содержит хотя бы один символ, то для всего текста строки будет создан токен DATE. Даже если линия начинается с commit или COMMITHASH, правило DATE будет использоваться, поскольку оно соответствует длинным последовательностям символов.
  • Наконец, для каждой новой строки будет создан токен NEWLINE.

Для решения проблемы вам необходимо будет выполнить одно из следующих действий. Точная стратегия зависит от большей проблемы, которую вы пытаетесь решить.

  • Измените правило DATE или перепишите его в соответствии с более конкретным форматом даты.
  • Используйте семантические предикаты и/или лексеры для ограничения местоположения (ов) на входе, где может быть произведен токен DATE.
+0

Спасибо за ответ, теперь я могу понять, что происходит в вышеуказанном случае. Стало более ясным, когда я распечатывал жетоны, на которые давал лексер.И для этого вопроса, и для вопроса, заданного в http://stackoverflow.com/questions/16364046/antlr4-mismatched-input/16365319#16365319 – Ramg

Смежные вопросы