我有以下yacc语法:
33 CompSt: "{" DefList StmtList "}"
34 | "{" error ";" DefList StmtList "}"
......
52 DefList: Def DefList
53 | %empty
54 Def: Specifier DecList ";"
55 | Specifier error ";"
56 | Specifier DecList error ";"
57 | Specifier VarDec "[" error ";"
58 | Specifier VarDec "[" INT error ";"
59 DecList: Dec
60 | Dec "," DecList
61 Dec: VarDec
62 | VarDec "=" Exp
我添加了第34条规则来处理当一个非法项目出现在一对大括号的开头时的情况。我认为这个规则是必要的(如果你有任何其他方法,请告诉我(,但有一个转移/减少警告:
33 CompSt: "{" . DefList StmtList "}"
34 | "{" . error ";" DefList StmtList "}"
error shift, and go to state 45
STRUCT shift, and go to state 2
TYPE shift, and go to state 3
error [reduce using rule 53 (DefList)]
我不明白为什么"错误";可以根据规则53减少,我不知道如何修复此警告。
非常感谢你的回复。
在shift-reduce冲突中,解析器有两个选项:reduce(一个特定的产品(,让先行标记稍后处理,或者shift先行标记。错误规则也没什么不同;至少在最初,error
被视为任何其他令牌。(特殊处理是error
移位后的重新同步,但那是在它移位后。(
因此,error
不会因产量53而减少。它是在error
之前的空Deflist
。当然,这种减少从来没有发生过,因为bison解决了有利于转移操作的转移-减少冲突,但它是在警告您,以防您认为减少空的Deflist
很重要。
尽管这种减少冲突的转变并不重要,但它有点丑陋,而且根本不清楚为什么你觉得有必要首先添加错误产生。您真的不需要那么多错误生成,因为错误实际上会在解析中冒泡。(我想,除非你试图在每种情况下产生特定的错误消息。(
我会删除错误生成55到58,将34更改为更简单的
| "{" error "}"
并添加
| error ';'
至Deflist
(生产后52(。