我正在使用一种使用偏向解析的语法(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
。
答案 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)
@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内置缓冲区无法保存令牌表达式。 编译解析器时是否收到错误?