开发者

Bison reduce errors. Why is it using that error placement instead of this one?

开发者 https://www.devze.com 2023-02-09 19:31 出处:网络
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 func

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:
    开发者_如何学C  funcBodyA
    | funcBodyS  mEOS
    | funcBodyEs aEOS
    | error aEOS  { doerror("funcBody", YYRECOVERING()); yyclearin; yyerrok; }


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

0

精彩评论

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