Bison Flex reduce/reduce 悬空 else 与中间动作发生冲突

Bison Flex reduce/reduce conflict on dangling else with mid action

我目前正在将我的一个有趣的项目移到 bison/flex 作为解析器,但在解决 reduce/reduce 冲突时遇到了问题:

// https://github.com/X39/yaoosl/blob/master/code-gen/yaoosl.y#L761-L766
ifthen: YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC codebody code_ifendnoelse
        | YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC ifthen_clsd YST_ELSE code_ifelse ifthen code_ifendelse
        ;
ifthen_clsd: codebody
           | YST_IF YST_ROUNDO expression code_ifstart YST_ROUNDC ifthen_clsd code_ifelse YST_ELSE ifthen_clsd code_ifendelse
           ;

注意:code_前缀的是中间动作

有人可以向我解释如何正确解决这个问题以及为什么 "go-to" 解决方案错误或不起作用吗? 谢谢,X39

因为直到 code_ifelse 这两个规则是相同的(并且假设 code_ifelse 是一个空规则,就像一个规则内的动作),它无法判断是否减少 code_ifelse 在 YST_ELSE 之前或之后。您可以通过使这两个规则与 code_ifelseYST_ELSE.

的顺序一致来修复它

语法的一些经验法则:

  • 不要对 '('')' 这样的单个字符标记使用符号名称——它只会混淆事物并使语法难以阅读和理解。
  • 除非绝对必要,否则不要使用规则内操作 -- 最好创建一个带有结束规则操作的单个标记规则来执行您需要的操作。