野牛中的未知类型 yypcontext_t

unknown type yypcontext_t in bison

上周我一直在与 bison 打交道,我想让我的解析器产生一些诊断性的、人们会理解的漂亮信息。

从这个 GNU website 开始,我开始在我的 yacc.y 文件中声明函数 int yyreport_syntax_error (const yypcontext_t *ctx),如下所示:

%{
/* some code above*/
extern int yyreport_syntax_error (const yypcontext_t *ctx);
%}

运行 bison用命令bison -d yacc.y,和我的lex.yy.c一起编译,然后clang;我的编译器,愉快地迎接我一个错误:

yacc.y:17:36: error: unknown type name 'yypcontext_t'
extern yyreport_syntax_error(const yypcontext_t *yyctx);
                                   ^
yacc.y:17:8: warning: type specifier missing, defaults to 'int'
      [-Wimplicit-int]
extern yyreport_syntax_error(const yypcontext_t *yyctx);
~~~~~~ ^
1 warning and 1 error generated.

是的,clang 报告没有名为 'yypcontext_t' 的类型。

我是不是忘了包含一个 bison 库或明确地定义了它?我不这么认为,因为其中 none 是在网站上写的。

如果您需要详细说明,我很乐意这样做。

野牛版本 3.6.3

MWE: test.y

%define parse.error custom

%{
#include <stdio.h>

extern FILE *yyin;
extern int yylex();
extern int yyreport_syntax_error(const yypcontext_t *yyctx);

%}

%token SP

%%

file : SP
     ;

%%

int main(){
   yyparse();
   return 0;
}

运行bison -d test.y后,执行gcc -c test.tab.c

yypcontext_t 未在 bison-generated headers 中导出,因此您无法在不同的翻译单元中定义 yyreport_syntax_error 函数。它必须放在您的 .y 文件中,并且必须放在最后,在第二个 %%.

之后

前向声明 yyreport_syntax_error 没有意义,因为 bison-generated 解析器包含前向声明。但是注意声明是

static int
yyreport_syntax_error (const yypcontext_t *yyctx);

进一步确认预期是 yyreport_syntax_error.y 文件本身中定义。

注意:我将此报告为文档错误 (https://lists.gnu.org/archive/html/bug-bison/2020-06/msg00054.html),因为在我看来文档确实应该提及这一事实。 (显然它会在即将发布的一些版本中。)