ANTLR4 Нет жизнеспособной альтернативы на входе - PullRequest
0 голосов
/ 04 июля 2019

Я реализую простой язык PseudoCode с ANTLR4, это моя текущая грамматика:

// Define a grammar called PseudoCode
grammar PseudoCode;
prog : FUNCTION SIGNATURE '(' ')'
        | FUNCTION SIGNATURE '{' VARB '}' ;

param: VARB | VARB ',' param ;

assignment: VARB '=' NUMBER ;

FUNCTION: 'function' ;
VARB: [a-z0-9]+ ;
SIGNATURE: [a-zA-Z0-9]+ ;
NUMBER: [0-9]+ | [0-9]+ '.' [0-9]+ ;

WS: [ \t\r\n]+ -> skip ;

Проблема в том, что после компиляции и генерации Parser, Lexer и т. Д. ... и затем запуска с grun PseudoCode prog -tree с вводом, например: function bla{bleh}

Я продолжаю получать следующую ошибку:

line 1:9 no viable alternative at input 'functionbla'

Может кто-нибудь указать, что не так с моей грамматикой?

1 Ответ

1 голос
/ 04 июля 2019

bla - это VARB, а не SIGNATURE, поскольку оно соответствует обоим правилам, а VARB стоит на первом месте в грамматике.Как вы определили свои правила лексера, идентификатор можно сопоставить только как SIGNATURE, только если он содержит заглавные буквы.

Самое простое решение этой проблемы - создать одно правило лексера для идентификаторов, а затем использоватьчто везде, где вы в настоящее время используете SIGNATURE или VARB.Если вы хотите запретить использование заглавных букв в определенных местах, вы можете просто проверить это условие в действии или прослушивателе, что также позволит вам создавать более четкие сообщения об ошибках, чем синтаксические ошибки (например, «заглавные буквы не допускаются в именах переменных»).

Если вам абсолютно необходимы заглавные буквы в именах переменных для синтаксических ошибок, вы можете определить одно правило для идентификаторов с заглавными буквами, а другое - без.Тогда вы могли бы использовать ID_WITH_CAPITALS | ID_LOWER_CASE_ONLY в местах, где вы хотите разрешить оба, и ID_LOWER_CASE_ONLY в тех случаях, когда вы хотите разрешить только строчные буквы.

PS: Вы также захотите убедиться, что ваш идентификаторправило не совпадает с числами (что в настоящее время соответствует VARB и SIGNATURE).В настоящее время NUMBER токены будут генерироваться только для чисел с десятичной точкой.

...