Мой язык имеет команды, которые могут быть параметр меньше или с параметрами, и «если» ключевое слово:Antlr4 лексер принимает неправильное правило
cmd1 // parameter-less command
cmd2 a word // with parameter: "a word" - it starts with first non-WS char
if cmd3 // if, not a command, followed by parameter-less command
cmd4 if text // command with parameter: "if text"
«если» признан if
только если это первая не- WS string в строке (давайте проигнорировать комментарии на данный момент ...)
Это мои правила грамматики:грамматика TestFlow;
// Parser Rules:
root: (lineComment | ifStat | cmd)* EOF;
lineComment : LC;
ifStat : IF;
cmd : CMD;
// Lexer Rules:
LC : '//' ~([\n\r\u2028\u2029])* -> channel(HIDDEN); // line comment
IF : 'if';
CMD : [-_a-zA-Z0-9]+ GAP LINE
| [-_a-zA-Z0-9]+
;
fragment GAP : [ \t]+;
fragment LINE : ~([\n\r\u2028\u2029])*;
Но мой лексический определяет 3-й линии как CMD
: if cmd3
, а не как if
следуют cmd3
, как мне нужно.
Какая у меня ошибка? как это исправить?
Я изначально исключил правила парсера, как мне показалось, как вопрос лексера. В любом случае, Я обновил свой вопрос, чтобы включить правила парсера, если это поможет. Второе: правило 'IF' появляется перед' CMD', поэтому я предполагаю, что он имеет приоритет. – Tar
Если вы обращаетесь к книге «Окончательный справочник ANTLR4», то у меня она есть, но это не очень хороший учебник «Начало работы». – Tar
'root: ((ifStat)? Cmd (lineComment)?) * EOF;' тоже не работает. Дело в том, что 'if cmd3' появляется как один токен, как я получаю от' commonTokenStream.getTokens() '. Итак, если это единственный токен, это то, что получает парсер от lexer, он не может их разделить. Вот почему я предполагаю, что это проблема lexer, а не парсер – Tar