在使用 `yy_create_buffer(yyin, YY_BUF_SIZE )` 创建缓冲区后,lex/flex 是否会正确解析 `FILE yyin` 中的所有标记?

Will lex/flex correctly parse all tokens in `FILE yyin` after create buffer with `yy_create_buffer(yyin, YY_BUF_SIZE )`?

在lex/flex中有一个函数yy_create_buffer,例如:

bp = yy_create_buffer(yyin,YY_BUF_SIZE );

它为 FILE yyin 创建缓冲区 bp,大小为 YY_BUF_SIZE

我想知道 FILE yyin 是否太大以至于 YY_BUF_SIZE 无法包含所有文本,lex/flex 会正确解析所有标记吗?

弹性缓冲区存储部分输入,以及足够的信息以继续处理输入。你不用担心有多少输入。

原来的 lex 扫描器没有缓冲。它一次只读取输入的一个字符,在字符数组 yytext 中构建当前标记。当令牌不是太大时,这工作得很好,但它不是最有效的解决方案。因此 flex 尝试通过一次读取数据缓冲区来加快扫描速度。 Flex 还避免了通过直接使用缓冲区中的数据来复制每个标记;在 flex 中,yytext 是一个指向缓冲区的指针,而不是一个单独的数组。

除了加速输入处理之外,flex 缓冲区还为您提供了许多额外的功能,包括提供内存缓冲区的能力和用于处理诸如 #include 指令之类的事情的缓冲区堆栈。

唯一的内存限制是令牌的大小。每个令牌在处理时都必须适合内存。当模式扫描到达缓冲区的末尾时,flex 将首先将令牌移动到缓冲区的开头,然后在必要时尝试调整缓冲区的大小。

您在调用 yy_create_buffer 时提供的大小是初始缓冲区大小,而不是其限制。面对巨大的token,flex会在必要时继续扩充buffer,直到内存分配失败。显然,理论上可以有一个如此大的令牌,以至于这是不可能的。因此,如果您希望输入流包含 PB 级数据,请不要使用 (.|\n)+ 这样的模式。 :-)

在原始 lex 中 yytext 是一个数组,而不是指针,调整大小是不可能的,编译时数组大小对标记长度设置了固定限制。 Flex 是这方面的改进,但它并未针对大型令牌进行优化,并且当您的应用程序尝试将数兆字节的数据作为单个令牌处理时会出现一些性能问题。