简体   繁体   中英

Bison yyerror ignore next token on grammar

So I'm having a litle problem on my Bison program, first be aware that my program works and is fully function what you see here is just an exerpt and sufficiant to help me.

basicaly the parser reads " vector(x,2) " the program is checking if the variable " x " already exists and if the number of elements" 2 " are greater then 1. I'm throwing yyerror when this situations dont happen. the problem is that the error is not ignoring the rest of the token. Let me show an example of vector(x,1), you will see that it should ignore the statement when reducing but is not.

Starting parse
Entering state 0
Stack now 0
Reducing stack by rule 1 (line 58):
-> $$ = nterm PROGRAM (1.1: )
Entering state 1
...
....
Entering state 24
Stack now 0 1 5 12 15 18 24
Next token is token PARENTSIS_RIGHT (1.1: )
Shifting token PARENTSIS_RIGHT (1.1: )
Entering state 33
Stack now 0 1 5 12 15 18 24 33
Reducing stack by rule 10 (line 87):
   $1 = token RESEV_VAR (1.1: )
   $2 = token PARENTSIS_LEFT (1.1: )
   $3 = token STRING (1.1: )
   $4 = token COMMA (1.1: )
   $5 = nterm ELEMENTS (1.1: )
   $6 = token PARENTSIS_RIGHT (1.1: )
        Erro: blalalala.
-> $$ = nterm DEFINE_VECTOR (1.1: ) //here it should not run this one should skip it
Entering state 9
Stack now 0 1 9
Reducing stack by rule 6 (line 65):
   $1 = nterm DEFINE_VECTOR (1.1: )
        VECTOR
-> $$ = nterm DECLARACAO (1.1: )

As you can see at the end he is running the reduction to DEFINE_VECTOR when i specify error.

%start PROGRAM

%%

PROGRAM:
       | PROGRAM STATMENT
       | PROGRAM error STATMENT
;

STATMENT: QUIT  { fclose(yyin); printf("\nBYE\n"); exit('0');}
    | DEFINE_VAR    { printf("\tVAR\n"); }
    | DEFINE_VECTOR { printf("\tVAR\n"); }
;

...
DEFINE_VECTOR: RESEV_VAR PARENTSIS_LEFT STRING COMMA ELEMENT PARENTSIS_RIGHT { 
            if($5<=1){
                 yyerror("Vector to small");
            }else{
                 if(check($3)==0){
                    createVar($3, 2, $5);
                 }else{
                    yyerror("Variable alrady exists");
                 }
            }
}
;

ELEMENTS: ELMENTINT
    | ELMENTFLOAT{ $$ = $1;}
;

SOLUTION:

%start PROGRAM

%%

PROGRAM:
       | PROGRAM STATMENT
       | PROGRAM error STATMENT
       | PROGRAM error PARENTSIS_RIGHT STATMENT // added here
;

STATMENT: QUIT  { fclose(yyin); printf("\nBYE\n"); exit('0');}
    | DEFINE_VAR    { printf("\tVAR\n"); }
    | DEFINE_VECTOR { printf("\tVAR\n"); }
;

...
DEFINE_VECTOR: RESEV_VAR PARENTSIS_LEFT STRING COMMA ELEMENT PARENTSIS_RIGHT { 
            if($5<=1){
                 yyerror("Vector to small");
                 YYERROR;  //added here
            }else{
                 if(check($3)==0){
                    createVar($3, 2, $5);
                 }else{
                    yyerror("Variable alrady exists");
                    YYERROR;  added here
                 }
            }
}
;

ELEMENTS: ELMENTINT
    | ELMENTFLOAT{ $$ = $1;}
;

yyerror is just a function that prints an error message. It is called by the bison parser when it has a syntax error, but you can also call it elsewhere to print an error. It has no effect on the parsing (it doesn't interrupt or change it -- it does not "throw")

If you want to affect the parsing, you need to use YYERROR (a macro that triggers a parser error, which the parser will then try to recover from). However, if you have a semantic error like this (not a syntax error), you probably don't want to do this, as there's no syntax to recover. You might want to use YYABORT to abort the parse immediately (return from yyparse). Or you might want to just continue parsing, to possibly identify other errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM