链接器错误:' yylex'

时间:2017-11-21 19:00:55

标签: linker-errors yacc

我试图从书中写一个简单的yacc示例,但我在编译时遇到错误。 这是我的example.l:

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

int yywrap() {return 1;}

这里是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);}

这里在example.y首先我得到一个错误:yylex()的隐含定义。 我看了这里(Generating a compiler from lex and yacc grammar)并找到了这个错误的解决方案(我添加

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

在我的示例的顶部。但是现在我得到了另一个我无法找到的解决方案的错误:

  

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

     

/tmp/ccOI4Fcj.o:在功能' yylex':y.tab.c :(。text + 0x877):多个   定义' yylex' /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x0):first   这里定义的是/tmp/ccOI4Fcj.o:(.bss+0x0):&ybspin'的多重定义   /tmp/ccQdHx7a.o:(.bss+0x0):首先在这里定义   /tmp/ccOI4Fcj.o:(.bss+0x8):' yyout'的多重定义   /tmp/ccQdHx7a.o:(.bss+0x8):首先在这里定义   /tmp/ccOI4Fcj.o:(.data+0x0):' yylineno'的多重定义   /tmp/ccQdHx7a.o:(.data+0x0):首先在这里定义   /tmp/ccOI4Fcj.o:(.bss+0x10):' yy_flex_debug'的多重定义   /tmp/ccQdHx7a.o:(.bss+0x10):首先在这里定义/tmp/ccOI4Fcj.o:In   function' yy_create_buffer':y.tab.c :(。text + 0x1b16):multiple   定义' yy_create_buffer'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x129f):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yywrap':y.tab.c :(。text + 0x24d5):   多重定义' yywrap'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1c5e):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyrestart':y.tab.c :(。text + 0x18e9):   多重定义' yyrestart'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1072):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyrealloc':y.tab.c :(。text + 0x2495):   多重定义' yyrealloc'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1c1e):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yy_switch_to_buffer':   y.tab.c :(。text + 0x1998):' yy_switch_to_buffer'的多重定义   /tmp/ccQdHx7a.o:lex.yy.c :(. text + 0x1121):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyalloc':y.tab.c :(。text + 0x247b):   多重定义' yyalloc'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1c04):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yy_delete_buffer':   y.tab.c :(。text + 0x1bac):' yy_delete_buffer'的多重定义   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1335):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyfree':y.tab.c :(。text + 0x24ba):   多重定义' yyfree'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1c43):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yy_flush_buffer':   y.tab.c :(。text + 0x1cfc):' yy_flush_buffer'的多重定义   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1485):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yypush_buffer_state':   y.tab.c :(。text + 0x1d99):' yypush_buffer_state'的多重定义   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1522):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yypop_buffer_state':   y.tab.c :(。text + 0x1e9d):' yypop_buffer_state'的多重定义   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1626):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yy_scan_buffer':y.tab.c :(。text + 0x20ab):   多重定义' yy_scan_buffer'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1834):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yy_scan_string':y.tab.c :(。text + 0x21a8):   多重定义' yy_scan_string'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1931):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yy_scan_bytes':y.tab.c :(。text + 0x21d4):   多重定义' yy_scan_bytes'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x195d):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyget_lineno':y.tab.c :(。text + 0x22d3):   多重定义' yyget_lineno'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a5c):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyget_in':y.tab.c :(。text + 0x22df):   多重定义' yyget_in'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a68):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyget_out':y.tab.c :(。text + 0x22ec):   多重定义' yyget_out'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a75):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyget_leng':y.tab.c :(。text + 0x22f9):   多重定义' yyget_leng'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a82):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyget_text':y.tab.c :(。text + 0x2306):   多重定义' yyget_text'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a8f):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyset_lineno':y.tab.c :(。text + 0x2313):   多重定义' yyset_lineno'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1a9c):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyset_in':y.tab.c :(。text + 0x2326):   多重定义' yyset_in'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1aaf):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyset_out':y.tab.c :(。text + 0x233c):   多重定义' yyset_out'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1ac5):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyget_debug':y.tab.c :(。text + 0x2352):   多重定义' yyget_debug'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1adb):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yyset_debug':y.tab.c :(。text + 0x235e):   多重定义' yyset_debug'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1ae7):首先在这里定义   /tmp/ccOI4Fcj.o:在函数' yylex_destroy':y.tab.c :(。text + 0x23d2):   多重定义' yylex_destroy'   /tmp/ccQdHx7a.o:lex.yy.c:(.text+0x1b5b):首先在这里定义collect2:   错误:ld返回1退出状态

你能帮我吗?

1 个答案:

答案 0 :(得分:1)

不要QueryResults<T>。我知道网上有很多这样的例子,但它们是错的(至少不是最佳做法)。

修复此问题可能会改变您构建项目的方式。你应该:

#include "lex.yy.c"

你会看到几个警告;你可以通过添加

来摆脱大部分
lex example.l
yacc -d example.y
gcc -Wall -o example y.tab.c lex.yy.c

到你的lex文件的开头(假设你实际上是使用flex)。您还可以通过将%option noinput nounput 添加到选项列表中来摆脱毫无意义的yywrap

此外,请勿从yacc操作中noyywrap

如果要在第一个换行符处终止解析,请使用return。但通常最好让输入的结尾终止解析,因为词法分析器通常会提前读取,因此即使提前终止,您也无法继续读取输入;缓冲但未处理的输入将丢失。