#parsing #antlr
#синтаксический анализ #antlr
Вопрос:
Я бы счел себя умеренно опытным во всей теме лексического / синтаксического анализа, сам написал небольшие и попробовал yacc / unicc и некоторые DSL, такие как xtext, ohm-js. Все это было более или менее просто после ознакомления с основами, но ANTLR действительно вызывает у меня головную боль.
У меня есть несколько странных сообщений об ошибках, поэтому я начал разбивать свою грамматику до минимума, чтобы отслеживать их, но теперь я снова натыкаюсь на стену (конечно, вероятно, очень глупая ошибка, как всегда, но, похоже, я не нахожу ее прямо сейчас ..)
Вот моя грамматика.g4: …
sourceFile : Statement ;
Statement : FuncDef | VarDef ;
FuncDef : 'function' IDENT '(' ')' BlockDef ;
VarDef : 'var' IDENT ';' ;
BlockDef : '{' Statement* '}' ;
IDENT : CHAR (CHAR | DIGIT)* ;
CHAR : [a-zA-Z_] ;
DIGIT : [0-9] ;
WS : [ t] -> channel(HIDDEN) ;
…
Попытка сопоставления function hello() { }
дает следующее:
…
$> function hello() { }
line 1:0 mismatched input 'function' expecting Statement
line 1:14 token recognition error at: '('
line 1:15 token recognition error at: ')'
line 1:17 token recognition error at: '{ '
line 1:19 token recognition error at: '}'
$>
…
Связанная функция прослушивателя не вызывается, в отличие от более крупной грамматики — на основе той же маленькой! — который всегда жаловался на несоответствие при hello — line 1:9 mismatched input '
hello ' expecting IDENT
, но затем запускается слушатель.
Спасибо за любые подсказки!
Комментарии:
1. В ANTLR вы должны использовать нижний регистр для нетерминалов. Токены начинаются с прописных букв, и правила синтаксического анализа отличаются. (В yacc / bison это просто соглашение. Lemon также делает это обязательным. ИМХО, это хорошая привычка.)
2. github.com/antlr/antlr4/blob/master/doc/lexer-rules.md (второй абзац)
3. Найдите существующую грамматику для ANTLR 4 и затем начните с нее, github.com/antlr/grammars-v4 Таким образом, вы можете избежать довольно многих болей.
Ответ №1:
В ANTLR вы должны использовать нижний регистр для нетерминалов. Токены начинаются с прописных букв, и правила синтаксического анализа отличаются.
См. https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md , особенно второй абзац. (Также раздел о фрагментах лексера на этой странице.)
Комментарии:
1. Спасибо за это! Действительно, я помню, как читал это, но забыл о причине в слушателе (для удобства чтения), правила начинаются с заглавной буквы, например, enterFuncdef для правила funcdef . Теперь он разветвляется по назначению. Думаю, мне придется прочитать окончательную ссылку на Antlr, а не просто просматривать ее 🙂 Может быть, вы знаете о каких-либо проектах интерпретатора / компилятора / компилятора среднего уровня, использующих Antlr, и не просто демонстрируете синтаксический анализатор, но и фактическое использование проанализированного текста через listener или walker?