我有一个关于yacc编译器的问题.我不编译简单的yacc语法.这是代码部分:
/*anbn_0.y */
%token A B
%%
start: anbn '\n' {printf(" is in anbn_0\n");
return 0;}
anbn: empty
| A anbn B
;
empty: ;
%%
#include "lex.yy.c"
yyerror(s)
char *s;
{ printf("%s, it is not in anbn_0\n", s);
Run Code Online (Sandbox Code Playgroud)
我用mac os x,我试试yo命令;
$ yacc anbn_0.y然后
$ gcc -o anbn_0 y.tab.c -ll给我错误.这是错误;
warning: implicit declaration of function 'yylex' is invalid in C99 [-Wimplicit-function-declaration]
yychar = YYLEX;
Run Code Online (Sandbox Code Playgroud)
为什么我会收到错误?
它是一个警告,而不是一个错误,所以如果你忽略它你应该没事.但如果你真的想要摆脱警告,你可以补充一下
%{
int yylex();
%}
Run Code Online (Sandbox Code Playgroud)
到.y文件的顶部
这是对这个问题的更复杂版本的答案,仅通过添加声明就不容易解决.
GNU Bison支持生成与Flex一起使用的重入解析器(使用Flex %option bison-bridge re-entrant).Berkeley Yacc提供兼容的实现.
以下是有关如何yylex为两个解析器生成器解决此未声明的指南.
有了一个可重入的"Bison桥接"词法分析器,声明yylex转变为:
int yylex(YYSTYPE *yylval, void *scanner);
Run Code Online (Sandbox Code Playgroud)
如果将此原型放在%{ ... %}Yacc解析器的初始头部分中,并使用Bison或Berkeley Yacc生成解析器,编译器会抱怨YYSTYPE未声明.
您不能简单地为其创建前向声明YYSTYPE,因为在Berkeley Yacc中,它没有union标记.在Bison,它是typedef union YYSTYPE { ... } YYSTYPE,但在Berkeley Yacc它是typedef { ... } YYSTYPE:没有标签.
但是,在Berkeley Yacc中,如果你在解析器的第三部分放置一个声明,它就在yylex调用的范围内!以下是Berkeley yacc的作品:
%{
/* includes, C defs */
%}
/* Yacc defs */
%%
/* Yacc grammar */
%%
int yylex(YYSTYPE *, void *);
/* code */
Run Code Online (Sandbox Code Playgroud)
如果这是由Bison生成的,则问题仍然存在:yylex调用范围内没有原型.
这个小修正使它适用于GNU Bison:
%{
/* includes, C defs */
#if YYBISON
union YYSTYPE;
int yylex(union YYSTYPE *, void *);
#endif
%}
/* Yacc defs */
%%
/* Yacc grammar */
%%
int yylex(YYSTYPE *, void *);
/* code */
Run Code Online (Sandbox Code Playgroud)
你去吧