Simple yacc grammars give an error
Solution 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
Solution 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.
tilt_y
Updated on July 28, 2022Comments
-
tilt_y over 1 year
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 ?