如何判断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
相关产品推荐
相关产品推荐

