用积分YYSTYPE使bison / flex解析器重新进入

Making bison/flex parser reentrant with integral YYSTYPE

我在按照步骤使我的bison / flex解析器以最小的麻烦重新进入时遇到麻烦。

问题似乎出在词法分析器中。由于所有解析器都是可重入的,因此我无法再直接分配yylval。相反,根据Flex手册,我必须调用此函数:

1
void yyset_lval ( YYSTYPE * yylvalp , yyscan_t scanner );

但是问题是,YYSTYPE是整数类型。它不是动态分配的值,也根本不是左值,因此我无法将指针传递给它!我是否缺少某些东西,如果没有,我应该如何设置yylvalue?我从来没有遇到过非重入解析器这个问题!

更新:
好的,我想我可能已经解决了整数类型问题。现在,由于未设置任何输入,解析器似乎崩溃了,并且我没有找到任何有关如何告诉词法分析器从何处读取输入信息的文档。

弹性档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
%{
#define YYSTYPE Token // Token is a typedef to an integral type
// following two lines added per suggestion from Chris Dodd
#define YYPARSE_PARAM yyscan_t scanner
#define YYLEX_PARAM scanner

%}
%option reentrant
%option bison-bridge

// ...

{D}+{IS}?               {
    *yylval = Tokenint(strtol(yytext,0,10));
     return(CONSTANT);
}

野牛文件:

1
2
3
4
5
6
7
%{
#define YYSTYPE Token
%define pure-parser
%lex-param {void * scanner}
%parse-param {void * scanner}
%token CONSTANT
// ...

在解析器的此行崩溃:

1
*yy_cp = yyg->yy_hold_char;

我怀疑我可能没有为解析正确初始化所有内容。手册在这个主题上非常令人困惑,经常引用类型或变量而没有说明它们来自何处或为什么使用它们。我通过这种方式调用解析:

1
2
3
void * scanner;
yylex_init(&scanner);
yyparse(scanner); // Note: was &scanner, this is wrong and will crash!

通过阅读源代码,yylex_init正在分配struct yyguts_t并将其清零。当我崩溃时,yy_cp是一个空指针,实际上整个struct yyguts_t仍然为零。因此,我怀疑我没有正确初始化某些东西,这导致它不知道从何处获取输入。

最终编辑:
我将在回答原始问题时将其标记为已关闭,然后将新问题重新打开作为新问题。


通常,要创建可重入的解析器/扫描器,您将在.l文件中使用%option bison-bridge,在.y文件中使用%define api.pure。 这使yylval成为yylex的参数,而不是全局变量。 此外,您还需要:

1
2
3
4
%{
#define YYPARSE_PARAM yyscan_t scanner
#define YYLEX_PARAM scanner
%}

.y文件顶部,以将额外的scanner参数通过解析器传递给词法分析器。

现在,如果YYSTYPEint(在.y文件中没有%unionYYSTYPE的声明),则只需说*yylval = whatever;,即可在.l中设置令牌值。