gpt4 book ai didi

c - Flex - 从字符串创建缓冲区状态而不将其设置为事件缓冲区

转载 作者:太空宇宙 更新时间:2023-11-04 01:32:34 25 4
gpt4 key购买 nike

Flex manual on Multiple Input Buffers

你可以在那里看到:

The following routines are available for setting up input buffers for scanning in-memory strings instead of files. All of them create a new input buffer for scanning the string, and return a corresponding YY_BUFFER_STATE handle (which you should delete with yy_delete_buffer() when done with it). They also switch to the new buffer using yy_switch_to_buffer(), so the next call to yylex() will start scanning the string.

然后你有 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;
}

推空行不通

老东西

我的期望

我希望 yylex 返回 0 意味着缓冲区结束(并给我一个操作它们的机会)

我也希望,除非我重新启动扫描器,否则它会在它停止的地方继续进行(所以 ab 如果一个缓冲区以 a 结尾而另一个以 b 开头,则 ab 将被匹配,除非我明确重启扫描仪)

其次,如何在不将 flex 设置为事件缓冲区的情况下准备字符串缓冲区。

我想我可以创建一个新的“空”缓冲区(请参阅链接中的创建缓冲区函数)推送它,然后将其推送到堆栈上。

当我从字符串创建缓冲区时,我希望该函数设置输入缓冲区,它是输入堆栈的顶部,这将无害地删除我的“空”缓冲区。

对于原本如此可爱的东西来说,这似乎相当困惑。

提问的原因

测试这个会非常困难。我还必须假设我知道 flex 如何正确工作,然后根据我认为它如何工作来设计通过或失败的测试,看看它是否确实如此。这会花费很长时间,而且即使是错误的,我也可能无法获得支持我的模型的结果。

最佳答案

token 不能跨越缓冲区边界——单个 token 的所有字符必须来自同一个缓冲区。最简单的方法就是将缓冲区想象成包含一个字符序列,后面跟着一个 EOF —— flex 将通过从当前缓冲区读取字符来匹配一个标记,如果没有标记匹配,将匹配默认的“匹配任何单个字符作为标记并回应它”的规则。您对 token 的操作代码可能会切换缓冲区,在这种情况下,下一个 token 将来自新缓冲区。缓冲区永远不会在 token 中间切换,也永远不会“自动”切换——您需要在代码中的某处进行显式切换。

当 flex 到达缓冲区的末尾(除 EOF 标记外没有剩余字符)时,它将匹配 <<EOF>>规则(可能切换到新缓冲区),或调用 yywrap (您可以将 yywrap 视为“默认”<<EOF>> 规则)。默认 yywrap不更改缓冲区并导致 yylex返回 0 token 。由于缓冲区未更改,如果您调用 yylex再次不改变缓冲区,它会再次做同样的事情。

yy_scan_string/bytes 切换到新缓冲区的事实是您通过保存当前缓冲区并恢复来解决的烦恼:

YY_BUFFER_STATE cur = YY_CURRENT_BUFFER;
YY_BUFFER_STATE n = yy_scan_string(str);
yy_switch_to_buffer(cur);

通常紧随其后的是yypush_buffer_state(n)。 .

关于c - Flex - 从字符串创建缓冲区状态而不将其设置为事件缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20290427/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com