尝试编程“包含”功能时,flex / bison程序中的调试断言失败错误

时间:2015-01-28 22:44:28

标签: c bison yacc flex-lexer lex

我得到一个"调试断言失败...表达式流!= 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文件中拆分代码行?)

1 个答案:

答案 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;,但我希望这是该查询的答案。