简单的yacc语法会出错

时间:2013-11-20 20:41:39

标签: yacc

我对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);

我使用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;

为什么会出错?

2 个答案:

答案 0 :(得分:9)

它是一个警告,而不是一个错误,所以如果你忽略它你应该没事。但如果你真的想摆脱警告,你可以添加

%{
int yylex();
%}

.y文件的顶部

答案 1 :(得分:8)

这是对这个问题的更复杂版本的答案,仅通过添加声明就不容易解决。

GNU Bison支持生成与Flex一起使用的重入解析器(使用Flex的%option bison-bridge re-entrant)。 Berkeley Yacc提供兼容的实现。

以下是有关如何为两个解析器生成器解决此未声明yylex的指南。

对于一个可重入的“Bison桥接”词法分子,yylex的声明变成了这个:

int yylex(YYSTYPE *yylval, void *scanner);

如果将此原型放在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 */

如果这是由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 */

你去。