野牛减少错误。为什么使用该错误放置而不是这个?

时间:2011-02-11 15:16:16

标签: yacc bison

我非常困惑。我的文件中有错误,未使用funcBodyLoop2 error aEOS

为什么呢?这就是困扰我的事情。 funcBodyLoop2有一个空规则,因此它永远不会失败。并且失败funcBodyLoop2必须至少减少一次才能尝试运行规则| funcBodyLoop2 funcBody通过查看这些规则,它可以获得错误的唯一地方是funcBody。所以我添加了| funcBodyLoop2 error aEOS(aEOS检查一个或多个语句结尾,这是新行和';')。因此,如果funcBodyLoop2已经减少,那么错误总是在| funcBodyLoop2 error aEOS?运行它我总是进一步减少到我想要的规则。我最后写| error aEOS只是为了看看会发生什么,我看到在我的错误后报告funcBodyLoop2 b。

我的问题是,为什么使用该规则或不使用funcBodyLoop2 error aEOS。我不明白。

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 个答案:

答案 0 :(得分:1)

如上所述,您的语法在funcBodyLoop2中的两个错误规则之间存在移位/减少冲突,并且第一个funcBodyLoop2错误规则与funcBody错误规则之间的减少/减少冲突。后者意味着funcBody错误规则永远不会触发,因为funcBody2规则将始终优先(它在文件中较早)。

因此,如果你在funcBody2的最开始时遇到错误(你试图解析一个,而第一个令牌是合法地开始funcBody2或在当前上下文中跟随空funcBody2的东西),它将触发第二个funcBody2错误(移位)然后丢弃令牌,直到它看到aEOS(因为那是适合那里的唯一合法的东西),然后它会移动并减少b错误规则。

如果在减少至少一个funcBody2后出现错误(因此不在第一个令牌中),那么它最终会触发第一个funcBody2错误规则(非b)。