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

Error handling 野牛:一个错误会导致额外但不正确的错误,error-handling,bison,Error Handling,Bison,在我的代码的类部分,如果我写了一个错误,一些行将被报告为错误,而它们不应该被报告。我将“|error”放在某些位置,在这些位置可以很好/安全地从错误中恢复,但我认为它没有使用它。也许是想在某个地方恢复中间表达 有没有办法强迫野牛在指定地点恢复?它是如何工作的?我可能做错了什么 我把错误行放在循环旁边。以下是一个例子: SomeRuleLoop: | Rule ',' SomeRuleLoop Rule: A | B | C | Error A:

在我的代码的类部分,如果我写了一个错误,一些行将被报告为错误,而它们不应该被报告。我将“
|error
”放在某些位置,在这些位置可以很好/安全地从错误中恢复,但我认为它没有使用它。也许是想在某个地方恢复中间表达

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

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

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

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

funcBodyLoop:
    | funcBodyLoop funcBody

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

我试着在第一个错误的行和第二个错误的行之间写#=。我写这篇文章是为了检查解析器是否仍在funcbody循环中。这并没有给出一个错误,事实就是这样。不管我添加了printf,字符串都没有打印出来,所以它可能不再在函数循环中了?如何解决此问题?

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

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

SomeRuleLoop:
        /* Nothing */
    |   Rule ',' SomeRuleLoop
    ;
这是一个正确的递归规则,表示“SomeRuleLoop”是一个空的令牌字符串,或者是一个后跟逗号和更多“SomeRuleLoop”的“规则”。请注意,这意味着“SomeRuleLoop”以逗号结尾,这可能不是您想要的

第一条规则应该是:

SomeRuleLoop:
        Rule
    |   SomeRuleLoop ',' Rule
    ;
注意,允许空的备选方案是很重要的,但是在任何地方添加它们都会使语法变得模棱两可(更多的移位/减少冲突)


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


但是,我不确定您的其他问题是什么…

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

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

SomeRuleLoop:
        /* Nothing */
    |   Rule ',' SomeRuleLoop
    ;
这是一个正确的递归规则,表示“SomeRuleLoop”是一个空的令牌字符串,或者是一个后跟逗号和更多“SomeRuleLoop”的“规则”。请注意,这意味着“SomeRuleLoop”以逗号结尾,这可能不是您想要的

第一条规则应该是:

SomeRuleLoop:
        Rule
    |   SomeRuleLoop ',' Rule
    ;
注意,允许空的备选方案是很重要的,但是在任何地方添加它们都会使语法变得模棱两可(更多的移位/减少冲突)


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


然而,我不确定你剩下的麻烦是什么…

强迫';'或者错误末尾的换行符将解决此问题。(
| error my|u end_of_statement
而不是
|error

强制“;”或者错误末尾的换行符将解决此问题。(
| error my|u end|u statement
而不是
|error

如果没有一些代码来帮助我们,几乎不可能有多大帮助。但它需要接近最小的代码,而不是几百行。@Jonathan Leffler:循环就在这里。我修改了我的问题。你知道Yacc(Bison)是区分大小写的,所以使用“Error”的选项与“Error”不同(Error是“内置”的,有一个特定的意思是w.r.t错误恢复)。@Jonathan Leffler:好的。我检查过了,我没有在任何地方使用“Error”,只有“Error”OK-祝你解决问题好运。冲突是令人恼火的。如果没有一些代码来帮助我们,几乎不可能有多大帮助。但它需要接近最小的代码,而不是几百行。@Jonathan Leffler:循环就在这里。我修改了我的问题。你知道Yacc(Bison)是区分大小写的,所以使用“Error”的选项与“Error”不同(Error是“内置”的,有一个特定的意思是w.r.t错误恢复)。@Jonathan Leffler:好的。我检查过了,我没有在任何地方使用“Error”,只有“Error”OK-祝你解决问题好运。冲突可能令人恼火。等等。。。你在跟我开玩笑。它是左递归的吗?不对?哎呀,我做错了。这可能会解决错误问题。当我把一切都搞定的时候,我会评论的。我很困惑。我将规则修改为左递归。我看到我的错误消息正在打印。但我还是犯了一个错误。我更新了问题等待等待。。。你在跟我开玩笑。它是左递归的吗?不对?哎呀,我做错了。这可能会解决错误问题。当我把一切都搞定的时候,我会评论的。我很困惑。我将规则修改为左递归。我看到我的错误消息正在打印。但我还是犯了一个错误。我更新了问题