1
votes

I am extremely confused. I have an error in my file and funcBodyLoop2 error aEOS is NOT used.

Why? This is what is bothering me. funcBodyLoop2 has an empty rule so it can never fail. And to fail funcBodyLoop2 must reduce at least once before it can attempt to run the rule | funcBodyLoop2 funcBody By looking at these rules the only place it can get an error is funcBody. So i added | funcBodyLoop2 error aEOS (aEOS checks of one or more end of statements, which are newlines and ';'). So since funcBodyLoop2 is already reduce should the error always be at | funcBodyLoop2 error aEOS? Running it i always got reduce to a rule further back then i wanted. I end up writing | error aEOS just to see what happens and i see funcBodyLoop2 b being reported after my error.

My question is, why is it using that rule or not using funcBodyLoop2 error aEOS. I dont understand.

funcBodyLoop2:
    | funcBodyLoop2 funcBody
    | funcBodyLoop2 error aEOS  { doerror("funcBodyLoop2", YYRECOVERING()); yyclearin; yyerrok; }
    | error aEOS  { doerror("funcBodyLoop2 b", YYRECOVERING()); yyclearin; yyerrok; }


funcBody:
      funcBodyA
    | funcBodyS  mEOS
    | funcBodyEs aEOS
    | error aEOS  { doerror("funcBody", YYRECOVERING()); yyclearin; yyerrok; }
1
There's not enough grammar show here to see what is going on, and your question is not at all clear, but error is completely unlike a normal terminal in what it does, so its probably that you're confused as to what it does. Post a more complete grammar, the exact input that is not doing what you expect, and what you expect to happen.Chris Dodd
@Chris Dodd: Ok i could do that in a few hours. But maybe just simply explaining how the error terminal is different from others would help. I can say simply now i expect an error in funcBodyLoop2 funcBody to be caught and handled in | funcBodyLoop2 error aEOS and to keep looping inside of funcBodyLoop2 but that isnt the caseuser34537
error rules are ignored until a state is reached when current lookahead can neither shift or reduce. At that point, it pops states off the stack looking for one with an error rule. When it finds one, it shifts the error token, and then discards input tokens until it finds one that is acceptable to the new current state. At that point it attempts to continue.Chris Dodd

1 Answers

1
votes

As written, your grammar has a shift/reduce conflict between the two error rules in funcBodyLoop2 and a reduce/reduce conflict between the first funcBodyLoop2 error rule and the funcBody error rule. The latter means that the funcBody error rule can never fire, as the funcBody2 rule will always take precedence (its earlier in the file).

So if you get an error at the very beginning of a funcBody2 (you're trying to parse one and the very first token is something that can't legally begin a funcBody2 or follow an empty funcBody2 in the current contex), it will trigger the second funcBody2 error (shift) and then throw away tokens until it sees an aEOS (since that's the only legal thing that fits there), which it will then shift and reduce that b error rule.

If you get an error after reducing at least one funcBody2 (so not in the very first token), then it ends up triggering the first funcBody2 error rule (non-b).