yydestruct 函数调用的参数太少 (flex&bison)

yydestruct too few arguments to function call (flex&bison)

我正在尝试制作一个可重入的 flex&bison 解析器,但我遇到了这个奇怪的错误:

too few arguments to function call, expected 5, have 4

我看到Bison生成的代码是这样的:

static void
yydestruct (const char *yymsg,
            yysymbol_kind_t yykind, YYSTYPE *yyvaluep, void *scanner, struct BisonOutput *out)
{  ...some code... }

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...
}

我的代码是这样的:

%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 ...

而Flex代码如下:

%{ 
#include "syntax_parser.h"
%} 
%option reentrant  bison-bridge noyywrap
blanks          [ \t\n]+ 
number          [0-9]+
%option noyywrap  
%% 
... bunch of rules ...

我真的迷路了。为什么野牛不将 scanner 插入 yydestruct 尽管在 yyparse 中明显使用它?

您不能在 %*-param 声明中放置两个参数。生成所需参数集的正确方法是:

%param { void* scanner }
%parse-param { struct BisonOutput* out }

Bison 并不真正解析 {} 之间的代码。它所做的只是识别它假定为参数名称的最后一个标识符。它还假定该代码是语法正确的单个参数声明,并且它是这样插入到原型中的。由于它实际上是两个参数,因此可以毫无问题地将其插入到原型中,但由于仅将一个参数插入到对函数的调用中,因此这些与原型不匹配。

(真的,void* scanner应该是yyscan_t scanner,有一个先验的typedef void* yyscan_t;。但也许不是真的更好。)

您也可以考虑将 struct BisonOutput 的声明放入 %code requires(或 %code provides)块中,以便它自动包含在 bison 生成的头文件中。