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

Bison错误恢复与括号平衡:截断行自动补全实现咨询

解决Bison截断括号行自动补全的方案

核心思路:用语义值栈替代内部栈访问

Bison没有公开接口允许在栈弹出前直接访问内部token栈,但可以通过两种更优雅的方式实现截断行补全:

1. 给语法规则绑定语义栈,错误时直接生成补全串

不要用简单的line: balanced error NEWLINE;跳过整行,而是让balanced规则的语义值维护当前未闭合括号的栈结构,触发错误时直接从这个栈生成对应闭合字符:

%union {
    struct {
        char stack[100];
        int top;
    } brace_stack;
}

%type <brace_stack> balanced

%%

line: balanced NEWLINE
    | balanced error {
        // 从语义栈生成补全字符串
        while ($1.top > 0) {
            char open = $1.stack[--$1.top];
            char close = (open == '(') ? ')' : 
                         (open == '[') ? ']' : '>';
            printf("%c", close);
        }
        // 手动跳过当前行剩余内容到换行符
        yyerrok;
        int tok;
        while ((tok = yylex()) != NEWLINE && tok != 0);
    } NEWLINE
;

balanced: /* 空规则 */ { $1.top = 0; }
        | balanced '(' { $1.stack[$1.top++] = '('; }
        | balanced ')' { $1.top--; }
        | balanced '[' { $1.stack[$1.top++] = '['; }
        | balanced ']' { $1.top--; }
        | balanced '<' { $1.stack[$1.top++] = '<'; }
        | balanced '>' { $1.top--; }
;

%%

这种方式完全基于语法解析的上下文维护括号状态,比词法栈更准确,因为它能感知语法规则的解析进度,不会和词法层面的无关token混淆。

2. 借助Bison内部结构(不推荐,兼容性差)

如果一定要碰Bison内部栈,可以尝试:

  • 开启YYERROR_VERBOSE,让Bison生成包含栈顶信息的错误提示
  • 在自定义yyerror函数中,直接读取Bison生成的yystack结构体(注意这是未公开的内部结构,不同版本可能有变化),但这种方式容易因为Bison版本更新而失效,仅适合临时调试。

总结

最可靠且优雅的方案是在语法规则的语义动作中维护括号栈,错误触发时直接用这个栈生成补全串,既不需要依赖Bison内部栈,也避免了词法栈的上下文脱节问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:46:07