You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bison编译文法规则时出现2个shift/reduce冲突的排查解决咨询

问题理解验证

你对冲突原因的判断完全正确。这两个冲突本质上是同一根源导致的:当解析器处于已匹配完pointer_opt的状态,遇到下一个输入为(时,存在两条合法推导路径:

  • 路径1:将(移入,匹配direct_declarator规则中的LPAR declarator RPAR分支,用于解析带括号的普通声明符,比如int (*a)里的(*a)
  • 路径2:先将空串归约为direct_abstract_declarator_opt,后续匹配function_abstract_declarator规则中的LPAR parameter_type_list RPAR分支,用于解析无标识符的抽象声明符,比如int (*)(int)里的(*)(int)
    LALR(1)解析器无法仅通过前看1个token(判断该走哪条路径,因此触发shift/reduce冲突。

冲突解决方法

问题的核心是array_abstract_declarator和function_abstract_declarator规则中使用了可空的direct_abstract_declarator_opt作为前缀,引入了不必要的空归约分支。只需要重构抽象声明符相关的文法规则,去掉可空前缀的设计即可解决冲突,修改后语义完全兼容原有规则:

原有需要删除的规则

direct_abstract_declarator_opt:
    %empty
    | direct_abstract_declarator
    ;

array_abstract_declarator:
    direct_abstract_declarator_opt LBRA assignment_expression RBRA
    ;

function_abstract_declarator:
    direct_abstract_declarator_opt LPAR parameter_type_list RPAR
    ;

替换后的新规则

direct_abstract_declarator:
    LPAR abstract_declarator RPAR
    // 直接支持无前缀的数组/函数抽象声明符
    | LBRA assignment_expression RBRA
    | LPAR parameter_type_list RPAR
    // 递归支持带前缀的嵌套结构
    | direct_abstract_declarator LBRA assignment_expression RBRA
    | direct_abstract_declarator LPAR parameter_type_list RPAR
    ;

修改完成后重新编译Bison文法,两个shift/reduce冲突会同时消失,原有所有合法的声明、类型名语法都可以正常解析。


内容的提问来源于stack exchange,提问作者Riomare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 00:15:07