Аккуратный способ различать идентификаторы и имена переменных (ANTLR)? - PullRequest
3 голосов
/ 02 декабря 2011

Как мы можем различить имя переменной и идентификатор в грамматике ANTLR?

VAR: ('A'..'Z')+ DIGIT*  ;
IDENT  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;

Часть грамматики (в ANTLR) не работает, потому что компилятор будет жаловаться, что IDENT может никогда не быть достигнут для некоторого ввода.Кажется, это классический хакер для писателей компиляторов, Хак лексеров

Для пользователей ANTLR. Не могли бы вы рассказать, как вы обходите это?Спасибо

1 Ответ

1 голос
/ 02 декабря 2011

zell писал:

Часть грамматики (в ANTLR) не работает, потому что компилятор будет жаловаться, что IDENT никогда не будет достигнут длянекоторый ввод.

Нет, это не правильно.Следующая грамматика:

grammar T;

parse
  :  .* EOF
  ;

VAR   : ('A'..'Z')+ DIGIT*  ;
IDENT : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;

fragment DIGIT : '0'..'9';

не выдает никаких ошибок или предупреждений.Лексер просто создает два типа токенов:

  1. , если что-то начинается с одной или нескольких заглавных букв ascii, за которыми следуют ноль или более цифр, создается VAR;
  2. , есличто-то начинается с строчной буквы или символа подчеркивания, затем следует ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*, создается IDENT.

Обратите внимание, что для этого IDENT никогда не может начинаться с заглавной буквы ascii: это будетвсегда становиться VAR.

Итак, если у вас есть правило синтаксического анализатора, которое выглядит так:

foo
  :  IDENT
  ;

и весь ввод "BAR", тогда будет ошибка синтаксического анализаторапотому что лексер не будет выдавать токен INDENT, но токен VAR, даже если синтаксический анализатор "запрашивает" IDENT.

Вы должны понимать, что независимо от того, что парсер запрашивает у лексера, лексер работает независимо от парсера.

...