Я работаю с грамматикой, которая использует внешний анализ (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
,
@Malcolm Роу написал:
Я предполагаю, что вы спрашиваете: «Как мне сделать то, что я хочу, чтобы это не сработало?», На что я не знаю ответа. Но если вы спрашиваете, что означает ошибка, это в руководстве по Flex. «’переполнение при отжиме flex scanner’: вы использовали unput (), чтобы отодвинуть так много текста, что буфер сканера не может содержать как текст возврата, так и текущий токен в yytext. В идеале сканер должен динамически изменять размер буфера в это дело, но в настоящее время это не так. «
Поскольку вы сталкиваетесь с системными ограничениями, я подозреваю, что это настолько хороший ответ, насколько это возможно сделать на данный момент.
Трудно сказать без кода, но моя интуиция указывает на
<<EOF>>
правило:
когда
(indent_stack.top() > 0)
Вы unput
в бесконечном цикле: EOF
всегда остается верным, и НАЧИНАЕТСЯ (перенос) (перенос — включающее начальное условие без <<EOF>>
кажется, ничего не делает в этом контексте.
Это очень легко иметь бесконечные циклы в <<EOF>>
правила, когда мы имеем
ветви без предложений yyterminate, yyaccept, return или аналогичных.
Проверьте, есть ли у вас рекурсивное определение какого-либо токена в вашем файле Lex. Ошибка просто указывает на то, что встроенный буфер lex не может содержать выражения токенов.
Вы получаете ошибку при компиляции вашего парсера?