3

我正在使用一种使用反面解析的语法(iow:制表符作为块分隔符)。该语法使用缩进堆栈来跟踪嵌套块,并在遇到 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(...).

但是,当我尝试对输入字符串进行 lex 时state = yy_scan_string(...),第一次调用会因yylex错误而崩溃flex scanner push-back overflow

4

4 回答 4

1

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

(indent_stack.top() > 0)

您处于unput无限循环中:EOF始终保持为真,并且 BEGIN(wrap) (wrap 是一个包含性的开始条件,没有 no <<EOF>>)在该上下文中似乎什么也不做。

<<EOF>>当我们有没有 yyterminate、yyaccept、return 或类似子句的分支时,规则中很容易出现无限循环。

于 2015-02-21T00:03:54.343 回答
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
%}
于 2019-05-07T21:21:42.927 回答
0

在评论中回答

@马尔科姆·罗写道:

我假设您要问的是“我如何做我想做的事而不会失败?”,我不知道答案。但是如果你问这个错误是什么意思,它在 Flex 手册中。"'flex 扫描仪推回溢出':您使用 unput() 推回了太多的文本,以至于扫描仪的缓冲区无法同时保存推回的文本和 yytext 中的当前标记。理想情况下,扫描仪应该动态调整缓冲区的大小这种情况,但目前没有。”

当您遇到系统限制时,我怀疑这是目前可以做出的最佳答案。

于 2015-02-17T19:13:27.977 回答
-2

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

于 2015-02-19T21:05:54.567 回答