开发者

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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜