Simple yacc grammars give an error

北慕城南 提交于 2019-12-21 04:54:11

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!