我试图从书中写一个简单的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退出状态
你能帮我吗?
答案 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
。但通常最好让输入的结尾终止解析,因为词法分析器通常会提前读取,因此即使提前终止,您也无法继续读取输入;缓冲但未处理的输入将丢失。