Это кажется распространенным недоразумением ANTLR
:
Обработка языка в ANTLR:
Обработка языка выполняется в двух строго разделенных фазах:
- Лексинг, то есть разбиение текста на токены
- Анализ, т. е. построение дерева разбора из токенов
Поскольку лексирование должно предшествовать синтаксическому анализу, возникает следствие : Lexer не зависит от анализатора, парсер не может влиять на лексику.
Лексинг
Лексинг в ANTLR работает следующим образом:
- все правила с верхний регистр первого слова - это правила lexer
- , лексер начинается с начала и пытается найти правило, которое наилучшим образом соответствует текущему входу
- , наилучшее совпадение - это совпадение с максимальной длиной, т.е. токен, полученный из добавления следующего входного символа к совпадению максимальной длины, не сопоставляется никаким лексерским правилам
- токены генерируются из совпадений: если одно правило соответствует максимальной длине совпадения, соответствующий токен равен pu пролить в поток токенов, если несколько правил соответствуют максимальной длине, соответствует первому определенному токену в грамматике, толкается в поток токенов
Пример: что не так с вашей грамматикой
Ваша грамматика имеет два правила, которые являются критическими:
FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;
Каждое совпадение, соответствующее TITLE, также будет соответствовать FILEPATH. И FILEPATH определяется до TITLE: Таким образом, каждый токен, который вы ожидаете стать заголовком, будет FILEPATH.
Для этого есть два намека:
- сохранить ваши правила лексера disjunct (никакой токен не должен соответствовать надмножеству другого).
- , если ваши жетоны преднамеренно соответствуют тем же строкам, а затем помещают их в правильном порядке (в вашем случае этого будет достаточно).
- , если вам нужен лексер, управляемый парсером, вам нужно перейти на другой генератор парсера: PEG-Parsers или GLR-Parsers сделают это (но, конечно, это может вызвать другие проблемы).
задан user32981 20 November 2013 в 17:18
поделиться