Я только начинаю использовать ANTLR. Я пытаюсь написать парсер для определений полей, которые выглядят так:
field_name = value
Пример:
is_true_true = yes;
Моя грамматика выглядит так:
grammar Hello;
//Lexer Rules
fragment LOWERCASE : [a-z] ;
fragment UPPERCASE : [A-Z] ;
fragment DIGIT: '0'..'9';
fragment TRUE: 'TRUE'|'true';
fragment FALSE: 'FALSE'|'false';
INTEGER : DIGIT+ ;
STRING : ('\''.*?'\'') ;
BOOLEAN : (TRUE|FALSE);
WORD : (LOWERCASE | UPPERCASE | '_')+ ;
WHITESPACE : (' ' | '\t')+ ;
NEWLINE : ('\r'? '\n' | '\r')+ ;
field_def : WORD '=' WORD ';' ;
Но когда я запускаю сгенерированный синтаксический анализатор на «working = yes;» я получаю сообщение об ошибке:
line 1:7 extraneous input ' ' expecting '='
line 1:9 extraneous input ' ' expecting WORD
Я не совсем понимаю, есть ли ошибка в сопоставлении с шаблоном WORD
или это что-то совсем другое?
похоже, вы не учитываете пробелы в поле def.
@ DanielA.White Спасибо! Это была ошибка.
В вашем примере есть пробелы, но ваш field_def
не учитывает их.
Поскольку довольно часто пробелы не имеют значения для вашей грамматики (т.е. в нем нет семантического значения, кроме разделения слов), ANTLR позволяет просто пропустить его:
В ANTLR 4 это делается
WHITESPACE : (' ' | '\t')+ -> skip;
NEWLINE : ('\r'? '\n' | '\r')+ -> skip;
В ANTLR 3 синтаксис
WHITESPACE : (' ' | '\t')+ { $channel = HIDDEN; };
NEWLINE : ('\r'? '\n' | '\r')+ { $channel = HIDDEN; };
При этом лексический анализатор токенизует ввод как обычно, но синтаксический анализатор понимает, что эти токены для него не важны, и ведет себя так, как если бы их не было, позволяя вам сохранять свои правила простыми и без необходимости добавлять необязательные пробелы повсюду.
Это определенно выглядит как API более высокого уровня, чем простые регулярные выражения, поэтому я удаляю тег.