Simple yacc grammars give an error

19,564

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.

Share:
19,564
tilt_y
Author by

tilt_y

Updated on July 28, 2022

Comments

  • tilt_y
    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 ?