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

如何在Bison中限制错误恢复仅在行首Token异常时触发

仅在行首Token错误时启用Bison错误恢复的实现方法

问题场景

我们有一套基于行的语法,只允许两种行格式:

start1 1
start2 1 2
  • start1后面必须紧跟一个数字
  • start2后面必须紧跟两个数字
  • 行首是start1或start2以外的单词,一律判定为非法输入

目前用Bison写的语法规则如下:

line:
    START1 number NEWLINE
  | START2 number number NEWLINE
  | error alnums NEWLINE

alnums: ALNUM | ALNUM alnums

number: ALNUM { parse_number(); }

现在遇到的问题:

  • 行首是非法单词(比如foobar 1)时,解析器会忽略整行完成错误恢复,这符合预期
  • 但合法行首后出现格式错误(比如start1 1 2 3)时,解析器也会自动错误恢复,这不符合需求

我们需要实现:只有行首单词无效时允许错误恢复,其他场景禁止自动丢弃Token,直接报错

解决方案

核心思路是拆分语法结构,让错误恢复规则只匹配「行首非法」的场景,避免被合法行首后的错误触发。

1. 拆分规则,明确行首合法性

把行的结构拆分为「合法行」和「非法行」两个独立分支,只给非法行添加错误恢复逻辑:

%token START1 START2 ALNUM NEWLINE

%%
input: /* 空 */ | input line ;

line: valid_line | invalid_line ;

// 合法行:严格匹配格式,错误时不做自动恢复
valid_line:
    START1 number NEWLINE
  | START2 number number NEWLINE
  ;

// 非法行首:仅这里启用错误恢复,吃掉整行(可在这里输出自定义错误信息)
invalid_line: error NEWLINE ;

number: ALNUM { parse_number(); } ;

2. 保留精准错误信息的优化版

如果需要通过alnums匹配非法行首后的内容,输出更具体的错误信息,可以调整invalid_line规则:

invalid_line: error alnums NEWLINE { 
    // 比如输出:"行首非法标记,后续内容:xxx"
  } ;

alnums: ALNUM | ALNUM alnums ;

为什么这样有效?

Bison的错误恢复规则是按匹配优先级触发的:当解析器遇到错误时,会优先尝试匹配最贴合当前状态的错误规则。通过拆分合法行和非法行的分支,确保只有行首不是START1/START2时,才会触发错误恢复;而合法行首后的格式错误,因为没有对应的错误恢复规则,会直接终止解析或抛出错误,不会自动丢弃Token。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:58:23