Flex给出“致命的扫描仪内部错误 - 错过缓冲区的结束”

时间:2012-12-18 20:28:37

标签: c bison yacc flex-lexer

我正在尝试使用flex来缓冲不断填充和重新填充的缓冲区。

我有多个线程使用自己独立的缓冲区副本。

在psuedo中,它在我的主程序中看起来像这样:

while(forever)
{
-fill buffer buf-
buf[length+1] = '\0';
buf[length+2] = '\0';
yy_scan_bytes(&buf, length+2);
yylex();
}

其中多个线程正在运行该循环,并且所有线程都拥有它们的buf。

我的lex文件中有一条规则如下:

<<EOF>> {yyterminate(); yy_delete_buffer(YY_CURRENT_BUFFER);}

试图在缓冲区运行后进行清理。

我不确定我是否正确这样做,因为这是我第一次尝试将flex扫描仪与另一个程序结合使用。我是否会更好地从flex中进行所有缓冲区处理,并将其与我的主程序中的extern声明相关联?

由于

1 个答案:

答案 0 :(得分:2)

问题是flex的默认扫描程序不是可重入的 - 它在全局变量中存储了一堆信息(包括要读取的当前缓冲区),所以如果你试图让多个线程同时扫描东西,它们会我会一个接一个地走。

您需要使用%option reentrant创建可重入扫描程序,然后为每个要使用的线程创建单独的yyscan_t,使用yylex_init进行初始化,然后作为额外参数传递适用于yylexyy_scan_bytes

此外,yyterminate会立即从扫描仪返回,因此永远不会进行yy_delete_buffer来电。您需要在扫描仪返回后调用它:

yyscan_t local;
yylex_init(&local);
while(forever)
{
    -fill buffer buf-
    buf[length+1] = '\0';
    buf[length+2] = '\0';
    YY_BUUFER_STATE bs = yy_scan_bytes(&buf, length+2, local);
    yylex(local);
    yy_delete_buffer(bs, local);
}