yyg->yy_buffer_stack 指向 yylex_init 之后的垃圾

yyg->yy_buffer_stack points to garbage after yylex_init

经过几个小时的调试,我发现 yyg->yy_bufer_stack 指向了一些不应该指向的内存,后来导致了分段错误:

(gdb) print yyg->yy_buffer_stack ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] : 0
Cannot access memory at address 0x2aaaaaab0c680
(gdb) print yyg->yy_buffer_stack
 = (YY_BUFFER_STATE *) 0x40000

当我尝试阅读生成的词法分析器的代码时,它充满了晦涩和非常可疑的引用,如负索引、故意将变量初始化为垃圾等等......一点都不明显这是怎么回事被设置为这个奇怪的值。关于可能导致它的任何猜测?下面是我调用 yyparse:

的代码
int main(int argc, char** argv) {
    int res;
    if (argc == 2) {
        yyscan_t yyscanner;

        yylex_init(&yyscanner);
        FILE* h = fopen(argv[1], "rb");

        if (h == NULL) {

            fprintf(stderr, "Couldn't open: %s\n", argv[1]);
            return errno;
        }
        yyset_in(h, yyscanner);
        fprintf(stderr, "Scanner set\n");
        res = yyparse(&yyscanner);
        fprintf(stderr, "Parsed\n");
        yylex_destroy(&yyscanner);
        return res;
    }
    if (argc > 2) {
        fprintf(stderr, "Wrong number of arguments\n");
    }
    print_usage();
    return 1;
}

您正在使用 地址 yyscanner 调用 yyparse,但您应该使用值来调用它。 yyscanner 的地址位于 C 堆栈中的某处,而 yyscanner 参数应指向一块内存,其中 yylex 存储其持久状态。那显然是行不通的。

请注意 Flex manual

中的示例
int main ( int argc, char * argv[] )
    {
        yyscan_t scanner;

        yylex_init ( &scanner );
        yylex ( scanner );
        yylex_destroy ( scanner );
        return 0;
    }