bison: one error causes additional but incorrect error
In the class section of my code, if I write an error a few lines will be reported as errors when they should not. I put '| error
' in certain locations where it's good/safe to recover from errors but I don't think it's using it. Maybe it's trying to resume mid expression someplace?
Is there a way I can force Bison to try to recover in designated locations? How does it work and what might I be doing wrong?
I put the error line next to the loop. Here is an example:
SomeRuleLoop:
| Rule ',' SomeRuleLoop
Rule:
A
| B
| C
| Error
A:
AA AAB AABC
| AA AAB AABC Z开发者_Python百科
...
Here is an example of my rules. I see "funcBody error" in my console however the next line gets an error because of the first error. Even though each funcBodyRule is standalone.
funcBodyLoop:
| funcBodyLoop funcBody
funcBody:
funcBodyRule
| error { printf("funcBody error"); $$=0; }
| '#' EQ { printf("still in funcBody\n"); $$=0; }
I tried writing #== between the line with the first error and the line with the 2nd. I wrote this to check if the parser is still in the funcbody loop. This doesnt give an error so it is. Nevermind i added a printf and the string isnt printed so maybe it isnt in the function loop anymore? how do i fix this?
Yacc and Bison normally use left-recursive rules, and the rules shown are not left-recursive.
As shown, the first rule is equivalent to:
SomeRuleLoop:
/* Nothing */
| Rule ',' SomeRuleLoop
;
This is a right-recursive rule which says that a 'SomeRuleLoop' is either an empty string of tokens or a 'Rule' followed by a comma and some more 'SomeRuleLoop'. Note that this means a 'SomeRuleLoop' ends with a comma, which is probably not what you had in mind.
The first rule should probably read:
SomeRuleLoop:
Rule
| SomeRuleLoop ',' Rule
;
Note that allowing for empty alternatives is important - but adding them everywhere tends to make the grammar ambiguous (more shift/reduce conflicts)
You also need to use the token 'error' (all lower case) rather than 'Error' (mixed case) to indicate a point where error recovery can occur.
However, I'm not sure what the rest of your troubles are...
Forcing ';' or newlines at the end of the error solves it. (| error my_end_of_statenent
instead of | error
)
精彩评论