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

如何判断yyerror()是否在错误恢复过程中被调用?及内部判定方法

解决Bison中yyerror()错误恢复状态判断的问题

针对你提出的两个问题,核心思路是自行维护一个状态标志,结合Bison文法中的错误恢复动作跟踪解析器是否处于错误恢复阶段,具体实现如下:

1. 定义状态标志

在解析器的C源文件(或共享头文件)中声明一个静态全局变量,用于标记当前是否处于错误恢复状态:

static int is_in_recovery = 0;

2. 在文法规则中更新标志

利用Bison的错误恢复规则(error符号),在进入错误恢复时设置标志;当解析器成功匹配后续合法语法单元、完成恢复时,重置标志:

// 示例:语句列表的错误恢复规则
stmt_list: stmt
         | stmt_list stmt
         | stmt_list error {
             // 进入错误恢复状态,设置标志
             is_in_recovery = 1;
             yyerrok; // 告知解析器恢复正常错误处理
             yyclearin; // 清空当前输入缓冲区,避免重复处理错误token
         }

// 示例:匹配合法语句时重置恢复标志
stmt: expr ';' { is_in_recovery = 0; }
    | if_stmt { is_in_recovery = 0; }
    | while_stmt { is_in_recovery = 0; }
    // 其他合法语句规则...

3. 在yyerror()中判断状态

现在可以直接在yyerror()内部通过检查标志变量,判断当前错误是否发生在错误恢复期间:

void yyerror(const char *msg) {
    if (is_in_recovery) {
        fprintf(stderr, "[错误恢复中] %s\n", msg);
    } else {
        fprintf(stderr, "[语法错误] %s\n", msg);
        // 非恢复阶段的严重错误可选择终止解析
        exit(EXIT_FAILURE);
    }
}

注意事项

  • 确保标志变量的作用域覆盖Bison生成的解析器代码和yyerror()函数,静态变量需放在同一个源文件中,或通过头文件声明为外部变量。
  • 必须在解析器成功匹配合法语法单元时重置标志,避免错误恢复状态被错误地持续保留。
  • 结合yyerrok和yyclearin宏可以让解析器更快从错误中恢复,同时保证标志状态的准确性。

内容的提问来源于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:34