Simple yacc grammars give an error

I have a question for the yacc compiler. I am not compiling a simple yacc grammar. Here is the code section:

/*anbn_0.y */ %token AB %% 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 am using mac os x and, I am trying to execute the yo command; $ yacc anbn_0.y and then $ gcc -o anbn_0 y.tab.c -ll and give me an error. Here is the error:

 warning: implicit declaration of function 'yylex' is invalid in C99 [-Wimplicit-function-declaration] yychar = YYLEX; 

Why am I getting an error message?

+6
source share
2 answers

This is 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 can add

 %{ int yylex(); %} 

at the top of your .y file

+8
source

Here is the answer to a more complex version of this problem that is difficult to solve by simply adding an ad.

GNU Bison supports the generation of paired pairs that work with Flex (using Flex %option bison-bridge re-entrant ). Berkeley Yacc provides a compatible implementation.

Here is a guide to solving this undeclared yylex for both parser generators.

With a repeat member, "Bison bridged" lexer, a yylex ad turns into this:

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

If you place this prototype in the initial header section %{ ... %} your Yacc parser and generate a parser using Bison or Berkeley Yacc, the compiler will complain that YYSTYPE not declared.

You cannot just create a forward ad 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 place an ad in the third section of the analyzer, it is in the yylex call area! 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 yylex .

This minor 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.

+7
source

Source: https://habr.com/ru/post/958514/


All Articles