野牛:一个错误导致额外但不正确的错误

时间:2010-11-19 23:15:23

标签: error-handling bison

在我的代码的类部分中,如果我写了一个错误,那么几行不会被报告为错误。我将'| error'放在某些位置,以便从错误中恢复是好的/安全的,但我不认为它正在使用它。也许它试图在某个地方恢复中期表达?

有没有办法可以强迫Bison尝试在指定地点恢复?它是如何工作的以及我可能做错了什么?

我把错误行放在循环旁边。这是一个例子:

SomeRuleLoop:
    | Rule ',' SomeRuleLoop
Rule:
      A
    | B
    | C
    | Error
A:
      AA AAB AABC
    | AA AAB AABC Z
...

以下是我的规则示例。我在我的控制台中看到“funcBody错误”但是由于第一个错误,下一行会出错。即使每个funcBodyRule都是独立的。

funcBodyLoop:
    | funcBodyLoop funcBody

funcBody:
      funcBodyRule
    | error { printf("funcBody error"); $$=0; }
    | '#' EQ { printf("still in funcBody\n"); $$=0; }

我尝试在第一个错误的行和第二个错误的行之间写#==。我写这个是为了检查解析器是否仍然在funcbody循环中。 这不会出错,所以它是。没关系我添加了一个printf并且字符串没有打印,所以它可能不再在函数循环中?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

Yacc和Bison通常使用左递归规则,并且显示的规则不是左递归的。

如图所示,第一条规则相当于:

SomeRuleLoop:
        /* Nothing */
    |   Rule ',' SomeRuleLoop
    ;

这是一个右递归规则,它表示'SomeRuleLoop'是一个空字符串或一个'Rule'后面跟一个逗号,还有一些'SomeRuleLoop'。请注意,这意味着'SomeRuleLoop'以逗号结尾,这可能与您的想法不同。

第一条规则应该是:

SomeRuleLoop:
        Rule
    |   SomeRuleLoop ',' Rule
    ;

请注意,允许空的替代方案很重要 - 但在任何地方添加它们往往会使语法模糊不清(更多的转移/减少冲突)


您还需要使用令牌“错误”(全部小写)而不是“错误”(大小写混合)来指示可能发生错误恢复的点。

但是,我不确定你的其他麻烦是什么......

答案 1 :(得分:0)

强迫';'或错误结束时的换行解决了它。 (| error my_end_of_statenent代替| error