Flex语法产生错误:扫描仪推回溢出

时间:2013-05-22 19:52:16

标签: c++ c lex flex-lexer

我正在使用一种使用偏向解析的语法(iow:Tabs作为块分隔符)。该语法使用缩进堆栈来跟踪嵌套块,并在遇到EOF时尝试用适当的关闭标记包装块。

std::stack<int> indent_stack;
int indent_size;

%x indent
%s normal
%s wrap

%%

<wrap>[ ]       {
                    if(indent_stack.top() > 0)
                    {
                        indent_stack.pop();
                        if(indent_stack.top() > 0) unput(' ');
                        return DEDENT;
                    }
                    else
                        yyterminate();
                }

<<EOF>>         { 
                    if(indent_stack.top() > 0)
                    {
                        BEGIN(wrap);
                        unput(' ');
                    }
                    else
                        yyterminate();
                }

<indent>[\t]    {indent_size++;}
<indent>[\n]    {indent_size = 0;}

<indent>.       {
                    unput(*yytext);
                    if(indent_size > indent_stack.top())
                    {
                        indent_stack.push(indent_size);
                        yytext[0] = '\0';
                        return INDENT;
                    }
                    else if(indent_size < indent_stack.top())
                    {
                        indent_stack.pop();
                        yytext[0] = '\0';
                        return DEDENT;
                    }
                    else
                    {
                        BEGIN(normal);
                    }
                }
/* And so begin <normal> rules. */

乍一看,这个语法出现,以便在输入文件时使用yyin = fopen(...)

但是,当我尝试输入输入字符串state = yy_scan_string(...)时,第一次调用yylex时出现错误flex scanner push-back overflow

4 个答案:

答案 0 :(得分:1)

Flex将其输入流存储在静态大小的缓冲区中。当您尝试将太多字符推回流时,并且没有足够的空间容纳它们时,会出现此错误。

如果您可以静态绑定您认为会压入缓冲区的最大字符数(也许是MB?),则可以通过在.ll顶部添加以下内容来覆盖缓冲区的大小。文件。这是一个hack,但是由于flex内缺乏动态内存管理,因此应该可以。

%{
  // Undefine the constant that flex uses when allocating its buffer
  #undef YY_BUF_SIZE

  // Pick some large constant. 
  // In my version flex 2.5.35 Apple(flex-31) the default is 16384
  #define YY_BUF_SIZE 1024*1024
%}

答案 1 :(得分:0)

Answered in the comments

@Malcolm Rowe写道:

  

我认为你所要求的是&#34;如果没有它失败,我该如何做我想要的?&#34;,我不知道答案。但是,如果您要问错误的含义,请参阅Flex手册。 &#34;'flex scanner push-back overflow':你使用unput()来回退扫描器的缓冲区无法同时保存yytext中的推回文本和当前标记的文本。理想情况下,扫描仪应该在这种情况下动态调整缓冲区大小,但目前它没有。&#34;

当你遇到系统限制时,我怀疑这是一个很好的答案,可以在这一点上做出。

答案 2 :(得分:0)

没有代码很难说,但我的直觉指向了 <<EOF>>规则: 当

(indent_stack.top() > 0)

你是unput - 在一个无限循环中:EOF始终为真,而BEGIN(换行)(换行是一个没有<<EOF>>的包容性开始条件)似乎正在做在这种背景下没有任何东西。

当我们有<<EOF>>规则时,很容易有无限循环 没有yyterminate,yyaccept,return或类似条款的分支。

答案 3 :(得分:-1)

检查Lex文件中是否有任何令牌的递归定义。错误只是表明lex内置缓冲区无法保存令牌表达式。 编译解析器时是否收到错误?