c++bisonerror-recovery

Bison error recovery (panic-mode) not working?


I've been reading up on how to make the Bison parsing "error resistant", and it seems pretty straightforward. No matter where i've looked, it pretty much comes down to the same simple solution.

Yet, i've been unable to make it work and i can't see the flaw. The parser keeps stopping/exiting instead of continuing/recovering...

What i have is basically a rule to treat all the keywords (and their patterns), like:

keywords:
    key1_rule
    | key2_rule
    | key3_rule
;

And above it, i have my file iterator rule:

file:
    %empty
    | file keywords
;

The problem i have is that sometimes the keywords are used in a pattern that isn't treated, but this isn't a problem because we don't want to capture these cases (and just want to ignore them). For example:

In these cases we want to ignore, the parser correctly launches an "unexpected token" error. In the example above the error would be "Parse error: syntax error, unexpected KEY3" (or "Parse error: syntax error, unexpected KEY2").

So from what i've seen, i thought the solution would be as simple as using the error token, like so:

file:
    %empty
    | file keywords
    | file error
;

I've also tried*:

keywords:
    key1_rule
    | key2_rule
    | key3_rule
    | keywords error
;

*and also tried: error '\n' and error '\n' { yyerrok; } (which i've seen in some cases)

Sadly, none of my tries were successful...and i keep getting the same "unexpected" error. I wonder if there's something i have to configure before being able to use it correctly...i've noticed that i had %option nodefault in my lexer file and tried removing it, but had the same result too.


Solution

  • This post here gave me a bit of insight on what the problem could be. In some cases the problem occurs because the stopping condition in the "error rule" is not met, which in his case was because the parser was ignoring/skipping the newline ('\n'). So the rule:

    error '\n' { yyerrok; yyclearin; }

    would never work...(since '\n' was never being captured)

    Thus, i isolated the error between 2 known tokens to rule out this possibility yet still got the error. After investigating a bit more, i discovered the problem was inside the yyerror function which was causing the program to exit.