Flex使用input()读取至EOF时扫描缓冲区出现段错误求助
Flex中使用yy_scan_string时input()读取至EOF触发段错误的问题
问题现象
下述Flex程序从标准输入读取内容时运行正常,但通过yy_scan_string扫描字符串缓冲区时会触发段错误。程序核心逻辑是通过一条规则匹配!后,调用input()读取至EOF(实际场景无法用!.*模式实现预期效果)。
标准输入下的正常运行步骤与输出
$ flex -o eof.c eof.lex $ cc -o eof eof.c $ echo -n 'one two!three four' | ./eof word:<one> -> 1 -> 2 word:<two> -> 1 buf:<three four> -> 3
错误复现场景
执行./eof 'one two !three four'时,程序在yy_get_next_buffer函数中触发段错误。排查发现词法分析器已识别到EOF,但即使设置了noyywrap选项仍未停止分析,因尝试查找下一个缓冲区而崩溃。
排查要点
-d调试选项未提供有效排查信息;- 段错误发生在
yywrap检查逻辑附近,理论上此时应识别到无更多输入; - Flex手册中
input()的示例将EOF视为错误,但本场景需将其作为合法结束条件; - 切换为可重入扫描器后问题依然存在;
input()在遇到EOF时返回0而非手册描述的EOF;- 使用
echo -n确保标准输入和字符串参数的字符序列完全一致; - 测试环境为flex 2.6.4,覆盖macOS和Linux平台;
- flex-help邮件列表已停止维护,无法通过该渠道获取支持。
示例代码
ALPHABETIC [a-zA-Z] WS [^a-zA-Z!] %option noyywrap nounput %% {ALPHABETIC}+ { printf("word:<%s>\n", yytext); return 1; } {WS}+ { return 2; } "!" { // gobble to end of input char buf[80]; for (int idx=0; (buf[idx] = input()); idx++) /* empty */ ; printf("buf:<%s>\n", buf); // YY_FLUSH_BUFFER; /* makes no difference */ return 3; } %% int main(int argc, char** argv) { switch (argc) { case 1: break; case 2: yy_scan_string(argv[1]); break; default: fprintf(stderr, "Usage: %s [string]\n", argv[0]); exit(1); } int token; while ((token = yylex()) != 0) { printf("-> %d\n", token); } }
后续分析
相关Stack Overflow问题提及input()返回0的异常行为,但未给出明确结论。目前怀疑这是Flex在缓冲区/EOF/yywrap处理逻辑中的bug,已提交为GitHub Issue #636。
内容的提问来源于stack exchange,提问作者Norman Gray
相关产品推荐
相关产品推荐

