我得到一个"调试断言失败...表达式流!= NULL"运行flex / bison程序时出错。这是相关代码,位于lex文件的顶部:
%x include_state
%{
#define MAX_INCLUDE_DEPTH 10
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
int include_stack_ptr = 0;
%}
...稍后在lex文件中:
include[ \t]*\" { BEGIN(include_state); }
<include_state>[a-zA-Z0-9 ]+ {
if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
{
fprintf(stderr, "Includes nested too deeply");
exit(1);
}
include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
yyin = fopen(yytext, "r" );
if (!yyin)
sprintf(err_str, "Error opening include file: %s", yytext);
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner),
yyscanner);
}
<include_state>\"; { BEGIN(INITIAL); }
...它试图传递的文字是:
include "hello.txt";
我正在尝试添加&#34;包含&#34;我的程序的功能。我正在使用win flex并赢得野牛。 (副作用:如何在lex文件中拆分代码行?)
答案 0 :(得分:2)
调试断言是Windows运行时告诉您尝试读取或写入FILE*
NULL
的方式,这意味着fopen
失败了。
在您的代码中:
yyin = fopen(yytext, "r" );
if (!yyin)
sprintf(err_str, "Error opening include file: %s", yytext);
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner),
yyscanner);
如果fopen
失败,你会产生一个很好的错误信息,但似乎没有对它做任何事情:你既不打印出来也不避免用{{切换到新的缓冲区1}} NULL
的值。
因此,您的yyin
似乎很可能失败了,您继续尝试阅读fopen
。
但您的代码还有另一个问题。
NULL
启动条件不是缓冲区的一部分。它是全球性的。切换到新缓冲区不保存启动条件(除非您将其保存在某处)。同样,除非您完成了保存启动条件的工作,否则在切换回原始缓冲区时无法恢复它。简而言之,因为当您切换缓冲区时处于启动条件flex
,当您开始对包含文件进行标记时,您仍然处于该启动条件,这意味着该文件开头的字符串(如果它开始使用include_state
)将用作要包含的文件名。这可能就是你[[:alnum:] ]
失败的原因。
我怀疑另一个明显的问题是剪切和粘贴问题。你有:
fopen
这是一个空行动的模式,后面是一个独立的动作(永远不会被执行)。动作必须开始与模式在同一行; <include_state>[a-zA-Z0-9 ]+
{
将继续阅读操作,直到找到匹配的flex
,因此您只需将}
放在与模式相同的行上:
{
我不确定你的意思是什么&#34;将代码分成不同的行&#34;,但我希望这是该查询的答案。