I have a problem with Bison's error handling. I have the following grammar (I have cut out only the relevant part). Flex sends its tokens to Bison and returns the terminal symbol "KW_CONFIGPARAM" if the string "ConfigParam" is parsed. IDENT is a pointer to a C++ string object.
statementlist : statement ';' { $$ = new string("statementlist"); }
| statementlist statement ';' { $$ = new string("statementlist"); }
;
statement : KW_CONFIGPARAM IDENT { $$ = new string("statement"); /* use $2, IDENT is used in main program */ }
;
I have the following destructor specified for strings like IDENT.
%destructor { printf ("free at line %d: %s\n",@$.first_line, $$->c_str()); delete($$); }
Now I have the following input. The first line is valid, the second line isn't (identifier is missing):
ConfigParam p;
ConfigParam;
Output:
In input 2:12 - 2:12 : syntax error
free at line 2: p
free at line 1: statementlist
Because of an error in the second line, Bison complains, returns a syntax error and calls the destructors of all objects on the parsing stack. Now I don't understand why the destructor of identifier "p" from the first line is called? It belongs to the first line and it was successfully parsed. The problem is that p is used in the main program and should be not removed by Bison.
If I choose as an (invalid) statement an arbitrary string ("foo") p is not removed by Bison.
ConfigParam p;
foo;
In input 2:1 - 2:3 : syntax error
free at line 1: statementlist
free at line 2: foo
Why this works?