Bison 解析器不报告 case 语句中的错误

Bison parser not reporting error within case statement

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

在上图中,我给出了使用 bison 生成的 compile 可执行文件,并提供了 syntax5.txt 。 如果你看到它在 => 2 时捕获了错误;适当地 它应该类似于 when 1 => 2; 但在它下面还有一个 which 也缺少文字。它出于某种原因没有选择它。错误总数应为 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;
} 

Bison 与 yacc 一样,在错误恢复后抑制前三个标记的错误消息。这避免了由于不精确的恢复而导致的级联错误。

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

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