在我的代码的类部分中,如果我写了一个错误,那么几行不会被报告为错误。我将'| 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并且字符串没有打印,所以它可能不再在函数循环中?我该如何解决这个问题?
答案 0 :(得分:1)
Yacc和Bison通常使用左递归规则,并且显示的规则不是左递归的。
如图所示,第一条规则相当于:
SomeRuleLoop:
/* Nothing */
| Rule ',' SomeRuleLoop
;
这是一个右递归规则,它表示'SomeRuleLoop'是一个空字符串或一个'Rule'后面跟一个逗号,还有一些'SomeRuleLoop'。请注意,这意味着'SomeRuleLoop'以逗号结尾,这可能与您的想法不同。
第一条规则应该是:
SomeRuleLoop:
Rule
| SomeRuleLoop ',' Rule
;
请注意,允许空的替代方案很重要 - 但在任何地方添加它们往往会使语法模糊不清(更多的转移/减少冲突)
您还需要使用令牌“错误”(全部小写)而不是“错误”(大小写混合)来指示可能发生错误恢复的点。
但是,我不确定你的其他麻烦是什么......
答案 1 :(得分:0)
强迫';'或错误结束时的换行解决了它。 (| error my_end_of_statenent
代替| error
)