问题
I have a question for yacc compiler. I do not compile simple yacc grammar. Here is the code section :
/*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);
I use mac os x and, i try yo command;
$ yacc anbn_0.y
and then
$ gcc -o anbn_0 y.tab.c -ll
and give me error. Here is the error ;
warning: implicit declaration of function 'yylex' is invalid in C99 [-Wimplicit-function-declaration]
yychar = YYLEX;
Why do I get an error ?
回答1:
Its a warning, not an error, so you should be fine if you ignore it. But if you really want to get rid of the warning, you could add
%{
int yylex();
%}
to the top of your .y
file
回答2:
Here is an answer to a more sophisticated version of this problem which isn't easily solved just by adding a declaration.
GNU Bison supports the generation of re-entrant parsers which work together with Flex (using Flex's %option bison-bridge re-entrant
). Berkeley Yacc provides a compatible implementation.
Here is a guide on how to solve this undeclared yylex
for both parser generators.
With a re-entrant, "Bison bridged" lexer, the declaration of yylex
turns into this:
int yylex(YYSTYPE *yylval, void *scanner);
If you place this prototype in the %{ ... %}
initial header section of your Yacc parser, and generate the parser with either Bison or Berkeley Yacc, the compiler will complain that YYSTYPE
is not declared.
You cannot simply create a forward declaration for YYSTYPE
, because in Berkeley Yacc, it does not have a union tag. In Bison, it is typedef union YYSTYPE { ... } YYSTYPE
, but in Berkeley Yacc it is typedef { ... } YYSTYPE
: no tag.
But, in Berkeley Yacc, if you put a declaration in the third section of the parser, it is in scope of the yylex
call! So the following works for Berkeley yacc:
%{
/* includes, C defs */
%}
/* Yacc defs */
%%
/* Yacc grammar */
%%
int yylex(YYSTYPE *, void *);
/* code */
If this is generated with Bison, the problem persists: there is no prototype in scope of the yylex
call.
This little fix makes it work for GNU Bison:
%{
/* includes, C defs */
#if YYBISON
union YYSTYPE;
int yylex(union YYSTYPE *, void *);
#endif
%}
/* Yacc defs */
%%
/* Yacc grammar */
%%
int yylex(YYSTYPE *, void *);
/* code */
There you go.
来源:https://stackoverflow.com/questions/20106574/simple-yacc-grammars-give-an-error