#parsing #antlr
#синтаксический анализ #antlr
Вопрос:
Если у меня есть грамматика ANTLR следующим образом:
grammar Test;
options {
language = Java;
}
rule : (foo | bar);
foo : FOO ',' FOO;
bar : BAR;
FOO: ('0'..'9') ;
BAR: ('a'..'z' | 'A'..'Z' | '0'..'9' | ' ') ;
WHITESPACE: (' ' | 't') { $channel=HIDDEN; };
И я использую тестовую строку:
12abc3
это (я полагаю) BAR
токен, который удовлетворяет bar
правилу и анализируется как таковой. Браво.
Однако, если у меня есть эта строка:
12
Я получаю line 1:2 mismatched input '' expecting ','
Это кажется довольно недетерминированным, хотя я уверен, что это не так. Я понимаю, что у меня уже проблемы с наличием двух токенов: FOO
и BAR
, которые принимают цифры. Но если анализатор собирается добиться успеха или потерпеть неудачу, он должен добиться успеха или потерпеть неудачу последовательно. Другими словами, в первом случае первым символом является 1 и, по-видимому, вычисляется как член BAR
токена, и, таким образом, анализатор направляется по успешному пути. Во втором случае тот ЖЕ самый первый символ вычисляется как FOO
токен, и, таким образом, путь обречен на неудачу, несмотря на то, что строка МОГЛА быть успешно bar
проанализирована. Почему несоответствие? Или я упускаю что-то более фундаментальное в ANTLR и / или синтаксическом анализе?
Ответ №1:
ANTLR не определяет тип токена, пока не увидит первый символ для следующего токена (или EOF). ANTLR также попытается найти самое длинное совпадение, вот почему вы видите ’12abc3′ как BAR, а не как FOO BAR. Во втором случае ANTLR будет использовать FOO для ’12’, потому что он указан первым в грамматике.
Ответ №2:
В дополнение к ответу Adam, вы должны понимать, что лексер и анализатор, хотя и определены в одной и той же грамматике, создаются в разное время. Сначала источник входных данных маркируется, и когда это произошло, только тогда анализатор работает с этими маркерами. Токены не создаются, пока анализатор просматривает источник (поток символов), чтобы обеспечить полное совпадение (т.Е. обозначить "12"
как BAR
). Тот факт, что "12"
обозначается как FOO
, заключается в том, что FOO
оно предшествует BAR
правилу и поэтому имеет более высокий приоритет в случае равного длинного совпадения.
Короче говоря: грамматики ANTLR не привязками.