我正在学习flex和bison,我想实现#include语句 我设法使用我在flex-manual中找到的一些代码来做到这一点,但我想检查相同的文件是否已经打开并进行分析。
例如正确的方法是:
但我希望避免这种情况发生:
我尝试保存我打开的每个文件的名称,以便在我打开一个新文件之前对它们进行比较但不知何故这不起作用...提前致谢
strcpy(filename[c], yytext);
c++;
for(i=0;i <20;i++){
if(strcmp(filename[i],yytext)!=0){
include_stack[include_stack_ptr++] =YY_CURRENT_BUFFER;
yyin = fopen( yytext, "r" ); yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
BEGIN(INITIAL);
}
else if(strcmp(filename[i],yytext)==0){
yyterminate(); }
}
答案 0 :(得分:0)
那段代码错了。你没有提到它是如何失败的,但以下是所有可能性。 (我将以#2作为直接问题,但修复可能导致其他问题。)
基本问题是测试的逻辑,可以翻译为&#34;从包含文件名列表的开头开始,检查要包含的文件是否与堆积值;如果是这样,将其推入包含堆栈。&#34;这会将新文件推送到包含堆栈20次,除非它恰好已存在于文件列表中。
此外,数字20
刚刚凭空消失。除非你已经超过filename
列表,否则此时c
将少于20,因此最终i
将达到值c
,此时文件名将比较相等,因此当前文件名已被放置在位置c
的向量中。这将导致所有文件名被拒绝。
您似乎无法检查c
是否超出filename
向量的大小。因此,您可以使用memcpy
覆盖随机内存。
解决所有这些问题后,您可能会考虑使用yycreate_buffer
,yypush_buffer_state
和yypop_buffer_state
而不是尝试自己维护缓冲区状态。使用flex
提供的接口比没有它们时尝试获取详细信息的风险要小得多。 (我知道这段代码是从flex手册中部分复制的,但你省略了重要的堆栈溢出测试。更容易使用flex手册中前面例子中的简单代码。)