Bison解析器未在case语句中报告错误

问题描述

我得到以下运行野牛解析器的输出Bison parser output on a file

在上图中,我给出了使用 bison 生成 compile 可执行文件,并提供了 Syntax5.txt 。 如果您看到它在=> 2时捕获了错误;适当地 它应该类似于1 => 2时; 但是在它下面还有一个缺少该文字的情况。由于某种原因,它没有选择它。错误总数应为5,显示为4。

这可能是什么原因。 这是我正在使用的parser.y文件。这与我定义语法的方式有关。

%{

#include <string>

using namespace std;

#include "listing.h"

int yylex();
void yyerror(const char* message);

%}

%define parse.error verbose

%token IDENTIFIER
%token INT_LIteraL

%token ADDOP MULOP RELOP ANDOP
%token  IF BOOL_LIteraL ARROW EXPOP REMOP OROP NOTOP CASE 
%token ELSE ENDCASE ENDIF OTHERS REAL THEN WHEN REAL_LIteraL 

%token BEGIN_ BOOLEAN END ENDREDUCE FUNCTION INTEGER IS REDUCE RETURNS

%%

    
function:   
    function_header variable body ;
    
function_header:    
    FUNCTION IDENTIFIER RETURNS type ';' |
    FUNCTION IDENTIFIER parameters RETURNS type ';' |
    error ';';
    
variable:
    IDENTIFIER ':' type IS statement_  variable |
    ;
    
    
parameters: parameter |
            parameter ',' parameters |
;           

parameter: IDENTIFIER ':' type ;

type:
    INTEGER |
    REAL |
    BOOLEAN ;

body:
    BEGIN_ statement_ END ';' ;
    
statement_:
    statement ';' |
    error ';' ;

statement:
    REDUCE operator reductions ENDREDUCE |
    IF expression THEN statement_ ELSE statement_ ENDIF |
    expression |
    CASE expression IS when OTHERS ARROW statement_  ENDCASE 
    ;

when: WHEN INT_LIteraL ARROW expression ';'|
      when WHEN INT_LIteraL ARROW expression ';' |
      error ';'|
       ;

       
     
operator:
    ADDOP |
    MULOP ;

reductions:
    reductions statement_ |
    ;
          
expression:
    expression OROP expression2 |
    expression2;
    ;



expression2: 
     expression2 ANDOP expression3 |
      expression3;
      ;

expression3: NOTOP expression3 |
              expression4 
         ;
        
expression4: relation;
         
relation:   
    relation RELOP term |
    term;

term:
    term ADDOP factor |
    factor ;
 
factor:
    factor MULOP factor2 |
    factor REMOP factor2 |
    factor2;
    
factor2: 
       factor3 EXPOP factor2 |
       factor3 
       ;

factor3: primary;
      

primary:
    '(' expression ')' |
    INT_LIteraL | 
    BOOL_LIteraL |
    REAL_LIteraL |
    IDENTIFIER ;
    
%%

void yyerror(const char* message)
{
    appendError(Syntax,message);
}

int main(int argc,char *argv[])    
{
    firstLine();
    yyparse();
    lastLine();
    return 0;
} 

解决方法

野牛像yacc一样,在错误恢复后会抑制前三个令牌的错误消息。这样可以避免由于恢复不精确而导致的一系列错误。

您可以使用yyerrok宏重新启用错误报告,但只能在操作的上下文中。 (因此,不能在yyerror的定义中使用它。)解析器动作通常是错误恢复动作;也就是说,包含error伪令牌的生产操作。

有关如何编写错误恢复结果的更多信息和示例,请参见error recovery chapter of the bison manual