On Jan 15, 2022, at 10:02, Akim Demaille wrote: > It very much depends on the *.l and the *.y files. But most of the time it > suffices to include something like > > %code provides { > int yylex (void); > void yyerror (const char *); > } > > in the first part of the *.y file (before %%). > > If you provide me with pointers to these packages, I can help finding the > appropriate fixes.
Thanks. flow-tools 0.68.5.1 is one example. Original homepage: https://code.google.com/archive/p/flow-tools/ GitHub copy which may or may not be official: https://github.com/adsr/flow-tools It has two .y files, lib/getdate.y which contains this in its prologue: static int yyparse (void); static int yylex (void); static int yyerror(const char * s); and it compiles fine, and src/aclyacc.y which does not contain that and complains: aclyacc.c:1232:16: error: implicit declaration of function 'yylex' [-Werror,-Wimplicit-function-declaration] yychar = yylex (); ^ aclyacc.c:1772:7: error: implicit declaration of function 'yyerror' [-Werror,-Wimplicit-function-declaration] yyerror (YY_("syntax error")); ^ Following your advice I added this to the prologue: int yylex(void); void yyerror(const char *); and it does compile now. But you said you didn't want to have bison generate this because a project might need it to be different. How can I know whether these prototypes are the right ones or if they need to be different? Is there some part of the .y file I should be looking at to determine that? Does a successful compile mean the prototypes were sufficiently correct? What about the static part? How would I have known that getdate.y needed the prototypes to be marked static? Or is that not needed there? What about the "int" return value of yyerror in getdate.y? Is that just a mistake and it should really be "void"? grok 0.9.2 is another example. Homepage: https://github.com/jordansissel/grok It has one .y file, conf.y, and its prototype contains: void yyerror (YYLTYPE *loc, struct config *conf, char const *s) { fprintf (stderr, "Syntax error: %s\n", s); } but it doesn't mention yylex and and it fails to build: conf.tab.c:1429:16: error: implicit declaration of function 'yylex' is invalid in C99 [-Werror,-Wimplicit-function-declaration] yychar = YYLEX; ^ conf.tab.c:745:16: note: expanded from macro 'YYLEX' # define YYLEX yylex (&yylval, &yylloc) ^ This invocation of yylex looks like it requires two parameters. I tried adding your prototype to the prologue as before: int yylex(void); But of course this fails: conf.tab.c:1302:1: error: conflicting types for 'yyparse' yyparse (struct config *conf) ^ conf.tab.h:116:5: note: previous declaration is here int yyparse (struct config *conf); ^ conf.tab.c:1495:23: error: too many arguments to function call, expected 0, have 2 yychar = yylex (&yylval, &yylloc); ~~~~~ ^~~~~~~~~~~~~~~~ conf.y:14:1: note: 'yylex' declared here int yylex(void); ^ dict 1.13.1 is another example. Homepage: https://sourceforge.net/projects/dict/ It has two .y files, clientparse.y and servparse.y. Neither mentions yylex or yyerror in its prologue and both fail to build: y.tab.c:1054:16: error: implicit declaration of function 'yylex' is invalid in C99 [-Werror,-Wimplicit-function-declaration] yychar = yylex (); ^ y.tab.c:1240:7: error: implicit declaration of function 'yyerror' is invalid in C99 [-Werror,-Wimplicit-function-declaration] yyerror (YY_("syntax error")); ^ y.tab.c:1351:3: error: implicit declaration of function 'yyerror' is invalid in C99 [-Werror,-Wimplicit-function-declaration] yyerror (YY_("memory exhausted")); ^ Adding your suggested prototypes to the prologue of both gives me a successful build: int yylex(void); void yyerror(const char *); magicpoint 1.13a is another example. Homepage: http://member.wide.ad.jp/wg/mgp/ Its one .y file, grammar.y, has a yyerror function but doesn't mention yylex and fails to build: y.tab.c:2155:16: error: implicit declaration of function 'yylex' is invalid in C99 [-Werror,-Wimplicit-function-declaration] yychar = yylex (); ^ Adding your suggested prototype to the prologue fixes it: int yylex(void);