1
votes

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
...

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?

2
It is going to be nigh on impossible to help much without some code to help us. But it needs to be close to minimal code, not several hundred lines..Jonathan Leffler
@Jonathan Leffler: Its where the loop is. I modified my questionuser34537
You know that Yacc (Bison) is case sensitive, so the alternative with 'Error' is not the same as 'error' (which is 'built in' and has a specific meaning w.r.t error recovery).Jonathan Leffler
@Jonathan Leffler: Ok noted. I checked and i dont use 'Error' anywhere, only 'error'user34537
OK - good luck with resolving the issue. Conflicts can be exasperating.Jonathan Leffler

2 Answers

1
votes

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...

0
votes

Forcing ';' or newlines at the end of the error solves it. (| error my_end_of_statenent instead of | error)