Re: implicit declaration of function 'yylex' is invalid in C99

Ryan Schmidt <[email protected]> Mon, 17 Jan 2022 04:07:39 -0600
Newsgroups gmane.comp.parsers.bison.bugs
Message-ID <[email protected]>
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);