首页 > 解决方案 > Bison Flex 减少/减少悬挂 else 与中间动作的冲突

问题描述

我目前正在将我的一个有趣的项目转移到 bison/flex 作为解析器,并且在解决减少/减少冲突时遇到了麻烦:

// 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_ 为前缀的东西是中间动作

有人可以向我解释如何正确解决这个问题以及为什么“首选”解决方案是错误的或不起作用?谢谢,X39

标签: cbisondangling-else

解决方案


由于这两个规则在之前是相同的code_ifelse(并且假设 code_ifelse 是一个空规则,就像一个规则中的操作),它无法判断是code_ifelse在 YST_ELSE 之前还是之后减少。您可以通过使两条规则与 和 的顺序一致来解决code_ifelseYST_ELSE

语法的一些经验法则:

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

推荐阅读