ANTLR не сообщает об ошибке при оценке строки, которая не соответствует моему определению грамматики

Я впервые работаю с ANTLR над проектом в Имперском колледже Лондона, и до сих пор он был действительно полезным. Я уже определил простую рекурсивную грамматику следующим образом

grammar Hello;      

execution: workflow;

workflow : Task 
         | workflow OPERATOR workflow 
         |'(' workflow OPERATOR workflow ')'                        
         |'(' workflow OPERATOR workflow ')' (OPERATOR workflow)*                        
          ;


Task : 'T' ('0'..'9')+ | 'WF' ('0'..'9')+;

OPERATOR: 'AND' | 'OR'  | 'XOR' |';' ;

WS  :   [ \t\n\r]+ -> channel(HIDDEN) ; 

оценивать строки как:

T6 ; (T4 AND T7) ; T5 ; ( (WF23 OR WF2) OR (T3 AND WF4) AND T4) AND T5 OR T11

и это работает отлично, моя проблема возникает, когда я пытаюсь оценить неправильную строку, как

T6 ; (T4 AND T7) ; T5 ; ( (WF23 OR WF2) OR (T3 AND WF4) AND T4) AND (T5;OR() T2) 

в соответствии с моими правилами после последнего И строка "(T5;OR() T2) " недопустима, поскольку не соответствует моему определению грамматики, но при тестировании я получаю дерево для строки

   T6 ; (T4 AND T7) ; T5 ; ( (WF23 OR WF2) OR (T3 AND WF4) AND T4)

и последняя часть "(T5;OR() T2) ", которая неверна, просто игнорируется.

Мой вопрос в том, что мне не хватает, что я должен сделать, чтобы получить ошибку, сказав, что "(T5;OR() T2) " не соответствует моему определению грамматики, может кто-нибудь знает??

большое спасибо

1 ответ

Решение

Лексер счастливо маркирует ваш некорректный ввод, и вы дали парсеру команду на анализ (действительный) execution, Это то, что он сделал. Если вы хотите заставить анализатор использовать весь поток токенов, поместите EOF в конце точки входа вашей грамматики:

execution: workflow EOF;

Если вы сейчас анализируете свои данные:

String source = "T6 ; (T4 AND T7) ; T5 ; ( (WF23 OR WF2) OR (T3 AND WF4) AND T4) AND (T5;OR() T2)";
HelloLexer lexer = new HelloLexer(new ANTLRInputStream(source));
HelloParser parser = new HelloParser(new CommonTokenStream(lexer));
parser.execution();

Вы получите следующий вывод:

строка 1:72 - нет приемлемой альтернативы на входе '(T4 И T7); Т5; ( (WF23 ИЛИ WF2) ИЛИ (T3 И WF4) И Т4) И (Т5; ИЛИ
строка 1:15 посторонний ввод ')' ожидание {, ОПЕРАТОР}
...
Другие вопросы по тегам