【发布时间】:2013-11-29 16:57:34
【问题描述】:
Flex manual on Multiple Input Buffers
你可以在那里看到:
以下例程可用于设置输入缓冲区以扫描内存中的字符串而不是文件。它们都为扫描字符串创建了一个新的输入缓冲区,并返回相应的 YY_BUFFER_STATE 句柄(完成后应使用 yy_delete_buffer() 删除)。他们还使用 yy_switch_to_buffer() 切换到新缓冲区,因此下一次调用 yylex() 将开始扫描字符串。
那你有yy_scan_string之类的
通常 Flex 的默认设置很好,我有一个文件要扫描,或者只需要一个扫描仪,但是这个任务是不同的。
我正在尝试创建一个能够扫描多个文件和一些字符串的扫描仪。它是可重入的,我以前从未使用过 YY_INPUT()。
所以我的问题如下:
当一个缓冲区完成并且没有任何东西可以扫描时,Flex 是否会将该状态从堆栈中弹出,如果有另一个状态开始扫描它是如何停止的?
我的意思是它是如何停止的,就好像它在一条规则的中途。假设我尝试匹配ab,如果一个状态以a 结尾,而另一个以b 开头,那该如何处理?
问题
/** Pushes the new state onto the stack. The new state becomes
* the current state. This function will allocate the stack
* if necessary.
* @param new_buffer The new state.
* @param yyscanner The scanner object.
*/
void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (new_buffer == NULL)
return;
yyensure_buffer_stack(yyscanner);
/* This block is copied from yy_switch_to_buffer. */
if ( YY_CURRENT_BUFFER )
{
/* Flush out information for old buffer. */
*yyg->yy_c_buf_p = yyg->yy_hold_char;
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
}
/* Only push if top exists. Otherwise, replace top. */
if (YY_CURRENT_BUFFER)
yyg->yy_buffer_stack_top++;
YY_CURRENT_BUFFER_LVALUE = new_buffer;
/* copied from yy_switch_to_buffer. */
yy_load_buffer_state(yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
按 null 不起作用
旧物
我的期望
我希望 yylex 返回 0 意味着缓冲区结束(并让我有机会操纵它们)
我还希望除非我重新启动扫描仪,否则它将继续从上次停止的地方继续(因此如果一个缓冲区以 a 结尾而另一个缓冲区以 b 开头,则 ab 将匹配,除非我明确地重新启动扫描仪)
其次,如何在不将 flex 设置为活动缓冲区的情况下准备字符串缓冲区。
我想我可以创建一个新的“空”缓冲区(请参阅链接中的创建缓冲区函数)推送它,然后将它推送到堆栈上。
当我从字符串创建缓冲区时,我希望该函数设置输入缓冲区,这是输入堆栈的顶部,它将无害地删除我的“空”缓冲区。
对于原本如此可爱的东西来说,这似乎很混乱。
询问原因
对此进行测试将非常困难。我还必须假设我知道 flex 是如何正确工作的,然后根据我认为它如何工作来设计通过或失败的测试,看看它是否真的有效。这需要很长时间,即使结果是错误的,我也可能无法获得支持我的模型的结果。
【问题讨论】:
标签: c bison flex-lexer