Проблемы, начиная с Antlr

#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?