Search code examples
compiler-errorscompiler-constructionbisonflex-lexer

Bison parser not reporting error within case statement


I am getting the following output of running a bison parser : Bison parser output on a file

In the above image i gave the compile executable generated using bison and provided the syntax5.txt. If you see it caught the error when => 2; properly it should be something like when 1 => 2; But below it there is one more when which is also missing the literal. Its not picking that for some reason. And total number of errors should be 5 its showing as 4.

what could be the reason for this. Here is the parser.y file that i am using. Its something to do with the way i have defined grammar.

%{

#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;
} 

Solution

  • Bison, like yacc, suppresses error messages for the first three tokens after an error recovery. This avoids a cascade of errors resulting from imprecise recovery.

    You can reenable error reporting using the yyerrok macro, but only in the context of an action. (So you can't use it in the definition of yyerror.) The parser action would typically be an error recovery action; that is, an action for a production which includes the error pseudo-token.

    For more information and examples of how to write error recovery productions, see the error recovery chapter of the bison manual.