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
相关产品推荐
相关产品推荐

