I'm trying to make a reentrant flex&bison parser but I got this strange error:
too few arguments to function call, expected 5, have 4
I can see that the code generated by Bison looks like this:
static void
yydestruct (const char *yymsg,
yysymbol_kind_t yykind, YYSTYPE *yyvaluep, void *scanner, struct BisonOutput *out)
{ ...some code... }
and
int
yyparse (void *scanner, struct BisonOutput *out)
{
...some code...
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, out); // <--- here void*scanner parameter is clearly missing
...some code...
}
My code is this:
%define api.pure full
%lex-param {void *scanner}
%parse-param {void *scanner, struct BisonOutput *out}
%{
struct BisonOutput{
int out;
};
#include "syntax_parser.h"
#include "lex.yy.h"
#include <stdio.h>
%}
%define api.value.type union
%token <int> NUM
...bunch of other tokens...
%%
...bunch of grammar rules...
%%
... main function and such ...
And Flex code is as follows:
%{
#include "syntax_parser.h"
%}
%option reentrant bison-bridge noyywrap
blanks [ \t\n]+
number [0-9]+
%option noyywrap
%%
... bunch of rules ...
I'm really lost. Why doesn't bison plug scanner
into yydestruct
despite clearly using it in yyparse
?
You are not allowed to put two parameters in a %*-param
declaration. The correct way to produce the set of parameters you want is:
%param { void* scanner }
%parse-param { struct BisonOutput* out }
Bison doesn't really parse the code between {
and }
. All it does is identify the last identifier which it assumes is the name of the parameter. It also assumes that the code is a syntactically-correct declaration of a single parameter, and it is inserted as such in the prototypes. Since it's actually two parameters, it can be inserted without problem into a prototype, but since only one argument is inserted into the calls to the function, these don't match the prototype.
(Really, void* scanner
should be yyscan_t scanner
, with a prior typedef void* yyscan_t;
. But perhaps it is not really better.)
You might also consider putting the declaration of struct BisonOutput
into a %code requires
(or %code provides
) block, so that it is automatically included in the bison-generated header file.