为什么在编译基本yacc程序时,我会得到yylex和yyerror的未定义符号?

为什么在编译基本yacc程序时,我会得到yylex和yyerror的未定义符号?,c,yacc,lex,c89,C,Yacc,Lex,C89,我正在用yacc/lex编写一个基本程序,在yaccC生成的yyerror和yylex源代码中,我得到了一个未定义的符号错误。如何指定这些文件是在lexlexer中生成的 以下是我尝试过的: readfile\u grammar.y %{ #include <time.h> #include <stdio.h> %} %union { struct tm d

我正在用yacc/lex编写一个基本程序,在
yacc
C生成的
yyerror
yylex
源代码中,我得到了一个
未定义的符号错误。如何指定这些文件是在
lex
lexer中生成的

以下是我尝试过的:

readfile\u grammar.y

    %{
    
    #include <time.h>
    #include <stdio.h>
    
    %}
    
    %union {
    
            struct tm       datetime;               /* DATE TIME VALUES */
            double          float_number;           /* 8 BYTES DOUBLE VALUE */
            long            integer_number;         /* 8 BYTES INTEGER VALUE */
    
    }
    
    %token  <datetime>              DATETIME
    %token  <float_number>          FLOAT_NUMBER
    %token  <integer_number>        INTEGER_NUMBER
    
    %%
    
    lastbid_lastask:        DATETIME ',' FLOAT_NUMBER ',' FLOAT_NUMBER ',' INTEGER_NUMBER   { printf("MATCH %lf %lf %ld\n", $3, $5, $7); }
                            ;
    
    %%
    
    int main(int argc, char *argv[]) {
    
            yyparse();
    
            return 0;
    
    }
在尝试编译源代码时,我遇到了提到的错误:

% make
yacc -d -oreadfile_grammar.c readfile_grammar.y
cc -std=c89 readfile_grammar.c
ld: error: undefined symbol: yylex
>>> referenced by readfile_grammar.c
>>>               /tmp/readfile_grammar-2d51ee.o:(yyparse)

ld: error: undefined symbol: yyerror
>>> referenced by readfile_grammar.c
>>>               /tmp/readfile_grammar-2d51ee.o:(yyparse)

ld: error: undefined symbol: yylex
>>> referenced by readfile_grammar.c
>>>               /tmp/readfile_grammar-2d51ee.o:(yyparse)

ld: error: undefined symbol: yyerror
>>> referenced by readfile_grammar.c
>>>               /tmp/readfile_grammar-2d51ee.o:(yyparse)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1

Stop.

在makefile中,在命令
cc$(CCFLAGS)readfile_grammar.c
中添加
-c
选项,以指定这只是一个模块,应编译为
.o
文件:

readfile_grammar.h readfile_grammar.o:  readfile_grammar.y
        yacc $(YFLAGS) -oreadfile_grammar.c readfile_grammar.y
        cc -c $(CCFLAGS) readfile_grammar.c

否则,cc会假定它是整个程序,并尝试将其链接到可执行二进制文件中,这当然会失败,因为它调用了其他文件中的函数。

flex和bison都不会生成
yyerror
。这是你的责任。一个简单的方法是
void yyrerror(const char*msg){fprintf(stderr,“%s\n”,msg);exit(1);}
。感谢您的评论。但是在更改了@NateEldredge建议这些错误消失的标志之后(我还有其他错误,但这是不同的历史)。没有与yyerror未定义符号相关的内容。您确定默认情况下lex不提供任何功能吗?我使用的是FreeBSD,而不是Linux/GNU。Lex不包括一个。从这里我看到,您还没有编译扫描仪,也没有构建最终的可执行文件;在执行最后一步之前,您不会看到链接器错误。(如果您以前从未编写过多文件C项目,您可能想搜索一些关于编译和链接的教程。)事实上,lex生成的扫描程序从不调用
yyerror
;它仅由解析器使用。所以如果发现Lex提供了一个,那真的很奇怪。你是对的,在调试了其他问题之后,我发现正如你所指出的,必须定义一个错误。谢谢你的解释,这很有帮助。
% make
yacc -d -oreadfile_grammar.c readfile_grammar.y
cc -std=c89 readfile_grammar.c
ld: error: undefined symbol: yylex
>>> referenced by readfile_grammar.c
>>>               /tmp/readfile_grammar-2d51ee.o:(yyparse)

ld: error: undefined symbol: yyerror
>>> referenced by readfile_grammar.c
>>>               /tmp/readfile_grammar-2d51ee.o:(yyparse)

ld: error: undefined symbol: yylex
>>> referenced by readfile_grammar.c
>>>               /tmp/readfile_grammar-2d51ee.o:(yyparse)

ld: error: undefined symbol: yyerror
>>> referenced by readfile_grammar.c
>>>               /tmp/readfile_grammar-2d51ee.o:(yyparse)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1

Stop.
readfile_grammar.h readfile_grammar.o:  readfile_grammar.y
        yacc $(YFLAGS) -oreadfile_grammar.c readfile_grammar.y
        cc -c $(CCFLAGS) readfile_grammar.c