Синтаксические ошибки в необязательных правилах в Antlr 4 не работают должным образом - PullRequest
0 голосов
/ 09 мая 2019

Я использую Antlr 4.7.2. Я пытаюсь реализовать оператор "if else":

Основная проблема заключается в том, что необязательное правило не включено в ParseTree, поэтому я думаю, что я не получаю синтаксические ошибки в этом необязательном правиле.

Одни из моих нынешних определений грамматики:

 prog       : stat+ ;                   

 stat       : func_declaration                              #rFuncDeclStat
            | if_stat                                       #rIfStat
            | while_stat                                    #rWhileStat     
            | for_stat                                      #rForStat
            | 'return' expr? STAT_END                       #rReturnStat
            | LET ID ('=' expr)? STAT_END                   #rVarDeclStat
            | var_reference '=' expr STAT_END               #rAssignStat
            | print_stat                                    #rPrintStat                     
            | expr STAT_END                                 #rFuncCallStat
            ;

block_stat  : '{' stat* '}' ;

if_stat     : if '(' expr ')' (stat | block_stat) else_stat?;

else_stat   : ELSE (stat | block_stat) ;

Все работает хорошо, когда я пишу правильный синтаксический код и запускаю грамматику, используя "org.antlr.v4.gui.TestRig":

if (2==2){
    let a = 4;
}
else{
    let b = 5;  //var declaration
}

Но когда я писал следующий код, правило "else_stat" не включалось в результат ParseTree, и Antlr4 не сообщает о какой-либо синтаксической ошибке.

if (2==2){
    let a = 4;
}
else{
    let b = 5;

Если я уберу "?" из правила "else_stat" (что делает его обязательным), Antlr4 включает "else_stat" в ParseTree и может определить ошибку и показать соответствующее сообщение: "Missing '}'".

Пожалуйста, кто-нибудь может направить меня по нужному адресу? Мне нужно знать, как заставить Antlr4 показывать синтаксическую ошибку, независимо от того, происходит ли она по необязательным правилам или нужно ли мне исправить определение грамматики или что-то еще.

Спасибо.

1 Ответ

3 голосов
/ 10 мая 2019

Обычно это не синтаксическая ошибка, если входной поток содержит больше входных данных, чем требуется по правилу, которое вы вызываете.Дополнительный ввод просто оставляется в потоке.Это позволяет вам вызывать правила в цикле, например.

Таким образом, если вы вызываете правило prog на входе if (2==2){ let a = 4; } else { let b = 5;, часть if (2==2){ let a = 4; } будет проанализирована как оператор if без else иelse { let b = 5; останется во входном буфере.

Поскольку это не то, что вы хотите, вы должны добавить EOF в конце вашего prog правила:

prog       : stat+ EOF;

The EOF сообщает ANTLR, что программа синтаксически допустима только в том случае, если после ее анализа во входных данных ничего не осталось.Это даст вам синтаксическую ошибку, которую вы хотите ввести.

...