Search code examples
linker-errorsyacc

Linker error: multiple definition of 'yylex'


I'm trying to write a simple example of yacc from the book but i'm getting errors while compiling. Here is my example.l:

%{
#include "y.tab.h"
%}
%%
a   return(A);
b   return (B);
.   return(yytext[0]);
\n  return('\n');
%%

int yywrap() {return 1;}

and here is example.y:

%token A B
%{
int yylex();
int yyerror(char *s);
%}
%%
start:  anbn '\n' {return 0;}
anbn:   A B
    | A anbn B
    ;
%%
#include "lex.yy.c"
int main(){
return yyparse();
}
int yyerror(char *s) {fprintf(stderr, "%s\n",s);}

Here in example.y first i got an error: Implicit definition of yylex(). I looked here (Generating a compiler from lex and yacc grammar) and find solution for this error(i add

`%{
int yylex();
int yyerror(char *s);
%}` 

in the top of my example.y) but now i'm getting another errors which solutions i couldn't find:

gcc lex.yy.c y.tab.c -o example

/tmp/ccOI4Fcj.o: In function 'yylex': y.tab.c:(.text+0x877): multiple definition of 'yylex' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x0): first defined here /tmp/ccOI4Fcj.o:(.bss+0x0): multiple definition of 'yyin' /tmp/ccQdHx7a.o:(.bss+0x0): first defined here /tmp/ccOI4Fcj.o:(.bss+0x8): multiple definition of 'yyout' /tmp/ccQdHx7a.o:(.bss+0x8): first defined here /tmp/ccOI4Fcj.o:(.data+0x0): multiple definition of 'yylineno' /tmp/ccQdHx7a.o:(.data+0x0): first defined here /tmp/ccOI4Fcj.o:(.bss+0x10): multiple definition of 'yy_flex_debug' /tmp/ccQdHx7a.o:(.bss+0x10): first defined here /tmp/ccOI4Fcj.o: In function 'yy_create_buffer': y.tab.c:(.text+0x1b16): multiple definition of 'yy_create_buffer' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x129f): first defined here /tmp/ccOI4Fcj.o: In function 'yywrap': y.tab.c:(.text+0x24d5): multiple definition of 'yywrap' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1c5e): first defined here /tmp/ccOI4Fcj.o: In function 'yyrestart': y.tab.c:(.text+0x18e9): multiple definition of 'yyrestart' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1072): first defined here /tmp/ccOI4Fcj.o: In function 'yyrealloc': y.tab.c:(.text+0x2495): multiple definition of 'yyrealloc' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1c1e): first defined here /tmp/ccOI4Fcj.o: In function 'yy_switch_to_buffer': y.tab.c:(.text+0x1998): multiple definition of 'yy_switch_to_buffer' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1121): first defined here /tmp/ccOI4Fcj.o: In function 'yyalloc': y.tab.c:(.text+0x247b): multiple definition of 'yyalloc' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1c04): first defined here /tmp/ccOI4Fcj.o: In function 'yy_delete_buffer': y.tab.c:(.text+0x1bac): multiple definition of 'yy_delete_buffer' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1335): first defined here /tmp/ccOI4Fcj.o: In function 'yyfree': y.tab.c:(.text+0x24ba): multiple definition of 'yyfree' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1c43): first defined here /tmp/ccOI4Fcj.o: In function 'yy_flush_buffer': y.tab.c:(.text+0x1cfc): multiple definition of 'yy_flush_buffer' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1485): first defined here /tmp/ccOI4Fcj.o: In function 'yypush_buffer_state': y.tab.c:(.text+0x1d99): multiple definition of 'yypush_buffer_state' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1522): first defined here /tmp/ccOI4Fcj.o: In function 'yypop_buffer_state': y.tab.c:(.text+0x1e9d): multiple definition of 'yypop_buffer_state' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1626): first defined here /tmp/ccOI4Fcj.o: In function 'yy_scan_buffer': y.tab.c:(.text+0x20ab): multiple definition of 'yy_scan_buffer' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1834): first defined here /tmp/ccOI4Fcj.o: In function 'yy_scan_string': y.tab.c:(.text+0x21a8): multiple definition of 'yy_scan_string' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1931): first defined here /tmp/ccOI4Fcj.o: In function 'yy_scan_bytes': y.tab.c:(.text+0x21d4): multiple definition of 'yy_scan_bytes' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x195d): first defined here /tmp/ccOI4Fcj.o: In function 'yyget_lineno': y.tab.c:(.text+0x22d3): multiple definition of 'yyget_lineno' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a5c): first defined here /tmp/ccOI4Fcj.o: In function 'yyget_in': y.tab.c:(.text+0x22df): multiple definition of 'yyget_in' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a68): first defined here /tmp/ccOI4Fcj.o: In function 'yyget_out': y.tab.c:(.text+0x22ec): multiple definition of 'yyget_out' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a75): first defined here /tmp/ccOI4Fcj.o: In function 'yyget_leng': y.tab.c:(.text+0x22f9): multiple definition of 'yyget_leng' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a82): first defined here /tmp/ccOI4Fcj.o: In function 'yyget_text': y.tab.c:(.text+0x2306): multiple definition of 'yyget_text' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a8f): first defined here /tmp/ccOI4Fcj.o: In function 'yyset_lineno': y.tab.c:(.text+0x2313): multiple definition of 'yyset_lineno' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a9c): first defined here /tmp/ccOI4Fcj.o: In function 'yyset_in': y.tab.c:(.text+0x2326): multiple definition of 'yyset_in' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1aaf): first defined here /tmp/ccOI4Fcj.o: In function 'yyset_out': y.tab.c:(.text+0x233c): multiple definition of 'yyset_out' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1ac5): first defined here /tmp/ccOI4Fcj.o: In function 'yyget_debug': y.tab.c:(.text+0x2352): multiple definition of 'yyget_debug' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1adb): first defined here /tmp/ccOI4Fcj.o: In function 'yyset_debug': y.tab.c:(.text+0x235e): multiple definition of 'yyset_debug' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1ae7): first defined here /tmp/ccOI4Fcj.o: In function 'yylex_destroy': y.tab.c:(.text+0x23d2): multiple definition of 'yylex_destroy' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1b5b): first defined here collect2: error: ld returned 1 exit status

Could you help me please?


Solution

  • Don't #include "lex.yy.c". I know that there are many examples of this floating around the net, but they're wrong (or at least, not best practice).

    Fixing this might change how you build your project. You should:

    lex example.l
    yacc -d example.y
    gcc -Wall -o example y.tab.c lex.yy.c
    

    You will see several warnings; you can get rid of most of them by adding

    %option noinput nounput
    

    To the beginning of your lex file (assuming you are actually using flex). You can also get rid of the pointless yywrap by adding noyywrap to the list of options.


    Also, don't return from a yacc action.

    If you want to terminate the parse at the first newline, use YYACCEPT. But it is usually better to just let the end of input terminate the parse, because the lexer generally reads ahead, and therefore even with the early termination, you will not be able to later continue reading input; buffered but unprocessed input will have been lost.