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

问题描述

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

bp = yy_create_buffer(yyin,YY_BUF_SIZE );

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

我想知道是否FILE yyin太大而YY_BUF_SIZE不能包含所有文本,lex/flex 会正确解析所有标记吗?

标签: filebufferflex-lexerlex

解决方案


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

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

除了加快输入处理速度之外,弹性缓冲区还为您提供了许多额外的功能,包括提供内存缓冲区和用于处理#include指令等内容的缓冲区堆栈的能力。

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

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

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


推荐阅读