1
votes

I am writing a parser with bison. I ran into a problem that bison detected the parsing error but didn't call yyerror.

Here are my scripts fragments to deal with class definition:

    %{ ...
       void yyerror(char *s); 
       Program ast_root;         /* the result of the parse  */
       Classes parse_results;    
    }%
    ...
    %%
    /* 
    Save the root of the abstract syntax tree in a global variable.
    */
    program     : class_list    { @$ = @1; ast_root = program($1); }
    ;

    class_list
    : class                     /* single class */
    { $$ = single_Classes($1);
    parse_results = $$; }
    | class_list class  /* several classes */
    { $$ = append_Classes($1,single_Classes($2));
    parse_results = $$; }
    | class_list error
    {
      $$ = $1;
    } 
    ; 

   /* If no parent is specified, the class inherits from the Object class. */
   class       : CLASS TYPEID '{' dummy_feature_list '}' ';' 
   { @$ = @2;
    SET_NODELOC(@2);
    $$ = class_($2,idtable.add_string("Object"),$4,
    stringtable.add_string(curr_filename)); }
    | CLASS TYPEID INHERITS TYPEID '{' dummy_feature_list '}' ';'
    {
      @$ = @2;
      SET_NODELOC(@2);         
      $$ = class_($2,$4,$6,stringtable.add_string(curr_filename)); 
   }
   ; 

The test file is like:

(* no error *)
class A {
};

(* error 1:  b is not a type identifier *)
Class b inherits A {
};

(* error 2:  a is not a type identifier *)
Class C inherits a {
 }; 

(* error 3:  keyword inherits is misspelled *)
Class D inherts A {
};

(* error 4:  closing brace is missing *)
Class E inherits A {
;

The running result is shown below:

"bad.cl", line 15: syntax error at or near OBJECTID = b

"bad.cl", line 19: syntax error at or near OBJECTID = a

"bad.cl", line 28: syntax error at or near ';'

Compilation halted due to lex and parse errors

The third error which has wrong spelling of inherits is not displayed.

I check the debug information. Error2 is like:

Stack now 0
Entering state 3
Reading a token: Next token is token CLASS (: )
Shifting token CLASS (: )
Entering state 1
Reading a token: Next token is token TYPEID (: )
Shifting token TYPEID (: )
Entering state 5
Reading a token: Next token is token INHERITS (: )
Shifting token INHERITS (: )
Entering state 9
Reading a token: Next token is token OBJECTID (: )
"bad.cl", line 19: syntax error at or near OBJECTID = a
Error: popping token INHERITS (: )
Stack now 0 3 1 5
Error: popping token TYPEID (: )
Stack now 0 3 1
Error: popping token CLASS (: )
Stack now 0 3
Shifting token error (: )
Entering state 7
Reducing stack by rule 4 (line 165):
   $1 = nterm class_list (: )
   $2 = token error (: )
-> $$ = nterm class_list (: )
Stack now 0
Entering state 3
Next token is token OBJECTID (: )
Error: discarding token OBJECTID (: )
Shifting token error (: )

I see that after Reading a token: Next token is token OBJECTID (: ) , bison detects the parsing error so it calls yyerror and print "bad.cl", line 19: syntax error at or near OBJECTID = a

But the information of error 3 is like:

Stack now 0
Entering state 3
Reading a token: Next token is token CLASS (: )
Shifting token CLASS (: )
Entering state 1
Reading a token: Next token is token TYPEID (: )
Shifting token TYPEID (: )
Entering state 5
Reading a token: Next token is token OBJECTID (: )
Error: popping token TYPEID (: )
Stack now 0 3 1
Error: popping token CLASS (: )
Stack now 0 3
Shifting token error (: )
Entering state 7

Obviously when it encounters Reading a token: Next token is token OBJECTID (: ) , bison detects an error but there is no error message printed so the yyerror has not been called.

I just feel so confused why this could happen since the above three errors are almost the same. Any help would be appreciated.

1

1 Answers

1
votes

Chspter six of the bison manual, which explains error recovery, includes this text:

Error recovery strategies are necessarily guesses. When they guess wrong, one syntax error often leads to another.…

To prevent an outpouring of error messages, the parser will output no error message for another syntax error that happens shortly after the first; only after three consecutive input tokens have been successfully shifted will error messages resume.

As you can see from the trace, only two tokens have been successfully shifted before the misspelled token is encountered.

For testing error recovery, it is usually best to use separate files for each error to be tested. Or at least separate the errors with a significant amount of valid program text.