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

LEX扫描器处理超长嵌套注释时输入缓冲区溢出问题排查与解决

问题:Flex扫描超长嵌套注释时出现缓冲区溢出错误

我定义了一个用于扫描嵌套注释的LEX扫描器,规则如下:

"(*" {
    int linenoStart, level, ch;

    linenoStart = yylineno;
    level = 1;
    do {
        ch = input();
        switch (ch) {
            case '(':
                ch = input();
                if (ch == '*') {
                    level++;
                } else {
                    unput(ch);
                }
                break;
            case '*':
                ch = input();
                if (ch == ')') {
                    level--;
                } else {
                    unput(ch);
                }
                break;
            case '\n':
                yylineno++;
                break;
        }
    } while ((level > 0) && (ch > 0));
    assert((ch >= 0) || (ch == EOF));
    
    if (level > 0) {
        fprintf(stderr, "error: unterminated comment starting at line %d", linenoStart);
        exit(EXIT_FAILURE);
    }
}

使用FLEX 2.6.4编译后,当扫描包含超过16382字符的注释的输入文件时,出现错误提示:

input buffer overflow, can't enlarge buffer because scanner uses REJECT

错误原因

  1. 默认缓冲区大小限制:Flex默认输入缓冲区大小为16384字节(16KB),当注释内容长度接近或超过这个阈值时,会触发缓冲区溢出。
  2. unput()导致扩容禁用:你的扫描器中使用了unput()函数,Flex的实现逻辑中,一旦扫描器调用unput()或REJECT,会自动禁用缓冲区自动扩容功能——这些操作依赖缓冲区的固定内存位置,扩容会破坏已存入缓冲区的回退字符状态,因此Flex拒绝扩容并抛出错误。

解决方法

方法一:手动增大缓冲区大小

在Flex源码开头添加缓冲区配置选项,直接设置更大的缓冲区(比如64KB),避免小缓冲区不足以容纳超长注释:

%option 8bit
%option buffer-size=65536  // 根据实际需求调整大小,单位为字节

方法二:改用Flex状态机处理嵌套注释(推荐)

放弃手动调用input()和unput()的方式,利用Flex内置状态管理和模式匹配处理嵌套注释,这种方式符合Flex设计风格,且不会触发缓冲区扩容限制:

%option 8bit
%option yylineno  // 启用行号统计

%x COMMENT  // 定义注释状态

%%
// 进入嵌套注释
"(*"                { BEGIN(COMMENT); int comment_level = 1; }

// 注释内遇到新的嵌套注释,层级加1
<COMMENT>"(*"       { comment_level++; }

// 注释内遇到结束标记,层级减1;层级为0时回到初始状态
<COMMENT>"*)"       { if (--comment_level == 0) BEGIN(INITIAL); }

// 注释内换行,更新行号
<COMMENT>\n         { yylineno++; }

// 忽略注释内的其他所有字符
<COMMENT>.          { /* do nothing */ }

// 注释未结束就遇到EOF,抛出错误
<COMMENT><<EOF>>    { fprintf(stderr, "error: unterminated comment starting at line %d", yylineno); exit(EXIT_FAILURE); }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:40:20