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

Bison中%prec处理非运算符优先级异常的技术咨询

用%nonassoc和%prec解决if-else移进归约冲突的疑问

我尝试用%nonassoc和%prec解决仅识别if-else结构的语法中的移进归约冲突,虽知晓其他解决方法,但为加深理解进行该尝试。

初始代码与冲突情况

初始代码如下:

%token IF PO PC ELSE STAT

%%
goal :                              statement

statement :                         IF PO PC statement 
                                    | IF PO PC statement ELSE statement 
                                    | STAT
%%

如预期出现移进归约冲突:

❯ bison -vdy test.y -Wcounterexamples
test.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
test.y: warning: shift/reduce conflict on token ELSE [-Wcounterexamples]
  Example: IF PO PC IF PO PC statement • ELSE statement
  Shift derivation
    statement
    ↳ 2: IF PO PC statement
                  ↳ 3: IF PO PC statement • ELSE statement
  Reduce derivation
    statement
    ↳ 3: IF PO PC statement                 ELSE statement
                  ↳ 2: IF PO PC statement •

成功解决冲突的修改方案

通过指定新token THEN与ELSE的优先级,代码修改为:

%token IF PO PC ELSE STAT

%nonassoc THEN
%nonassoc ELSE

%%
goal :                              statement

statement :                         IF PO PC statement %prec THEN
                                    | IF PO PC statement ELSE statement %prec ELSE
                                    | STAT
%%

此时无警告或错误。

修改失败的两种情况

情况1:将非关联token ELSE改为任意名称ABC

代码修改为:

%token IF PO PC ELSE STAT ABC

%nonassoc THEN
%nonassoc ABC

%%
goal :                              statement

statement :                         IF PO PC statement %prec THEN
                                    | IF PO PC statement ELSE statement %prec ABC
                                    | STAT
%%

出现完全相同的警告:

❯ bison -vdy test.y -Wcounterexamples
test.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
test.y: warning: shift/reduce conflict on token ELSE [-Wcounterexamples]
  Example: IF PO PC IF PO PC statement • ELSE statement
  Shift derivation
    statement
    ↳ 2: IF PO PC statement
                  ↳ 3: IF PO PC statement • ELSE statement
  Reduce derivation
    statement
    ↳ 3: IF PO PC statement                 ELSE statement
                  ↳ 2: IF PO PC statement •

情况2:保留ELSE名称但移除%prec THEN

此时同样会出现上述移进归约冲突。

我的推断与疑问

我推断THEN token会识别%prec指定的优先级,但ELSE token仅识别规则中的最后一个非终结符,而非%prec指定的优先级。

想请教%prec的具体工作原理,以及如何调试此类错误?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 10:16:13