如何解决为什么 Bison 可以将“错误”项减少为空规则
我有以下 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来处理一对大括号开头出现非法项的情况。我认为这个规则是必要的(如果你有其他方法,请告诉我),但有一个shift/reduce警告:
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(特定的产生式),让先行标记在之后处理,或者 转移 前瞻令牌。错误规则也不例外; error
至少在最初被视为任何其他标记。 (特殊处理是 error
移位后的重新同步,但那是在移位之后。)
因此,产生式 53 减少的不是 error
。而是 Deflist
之前的空 error
。当然,这种减少永远不会发生,因为 bison 解决了 shift-reduce 冲突而有利于 shift 操作,但如果您认为减少空 Deflist
很重要,它会警告您。
虽然这个 shift-reduce 冲突并不重要,但它有点难看,而且根本不明白为什么你觉得需要首先添加错误产生。你真的不需要那么多错误产生,因为错误有效地使解析冒泡。 (除非你试图在每种情况下产生特定的错误消息,我想。)
我会删除错误产生式 55 到 58,将 34 更改为更简单的
| "{" error "}"
并添加
| error ';'
到Deflist
(生产 52 之后)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。