Simple yacc grammars give an error
Asked Answered
V

2

8

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 ?

Vociferance answered 20/11, 2013 at 20:41 Comment(1)
You're not getting an error -- that is a warning. Its pretty much self-explanatory -- the version of yacc you are running is producing code following the old C89 standard (or even older), not the newer C99 standard.Sim
S
18

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

Sim answered 20/11, 2013 at 23:12 Comment(5)
This won't work if you're using a re-entrant parser, and yylex has a YYSTYPE * parameter. The YYSTYPE type is not known at that point in the file. And you should make that int yylex(void), avoiding the pre-ANSI non-prototype syntax.Provenience
If you use byacc (Berkeley Yacc), you can put the declaration after the grammar in the last section following the last %%, and everything is cool: the generated parser is still in scope of that. That doesn't work in Bison.Provenience
@Kaz: Nothing is needed in bison and Berkeley yacc as they properly declare yylex in the skeleton before trying to use it (and include all the relevant stuff for reentrant, if you're using that). You only need to add a declaration for ancient versions of AT&T yacc that assume the implicit declaration.Sim
My recent experience with Bison 2.5 and Byacc 1.9 20110908 tells me otherwise. Neither of them add any yylex declaration to y.tab.c. Perhaps newer versions of the tools do things differently. I noticed that Bison 3.x (of which I have an installation on a Solaris machine) declares yyparse in y.tab.h which 2.5 doesn't do. I will look for yylex next time I'm working on that machine.Provenience
same, I'm using bison 3.3.2, and neither the .tab.c nor .tab.h files declare yylex. This version is from 2019, so is there a reason it doesn't declare the function?South
P
11

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.

Provenience answered 5/8, 2014 at 14:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.