使用整数YYSTYPE使bison / flex解析器可重入

时间:2012-09-17 23:06:25

标签: bison flex-lexer reentrancy

我无法按照步骤使我的bison / flex解析器以最小的麻烦重新进入。

问题似乎出现在词法分析器中。由于一切解析器都是可重入的,我不能再直接指定yylval。相反,根据the Flex manual,我必须调用此函数:

void yyset_lval ( YYSTYPE * yylvalp , yyscan_t scanner );

但问题是,YYSTYPE是一个整体类型。它不是一个动态分配的值,它根本不是左值,所以我不能传递一个指向它的指针!我错过了什么,如果不是,我该如何设置yylvalue?我从来没有遇到过这种非重入解析器的问题!

更新: 好吧,我想我可能已经超越了整体类型的问题。现在解析器似乎崩溃,因为没有设置输入,我没有找到任何关于如何告诉词法分析器从何处读取输入的文档。

Flex文件:

%{
#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); 
}

野牛档案:

%{
#define YYSTYPE Token
%define pure-parser
%lex-param {void * scanner}
%parse-param {void * scanner}
%token CONSTANT
// ...

在解析器的这一行发生崩溃:

*yy_cp = yyg->yy_hold_char;

我怀疑我可能没有为解析正确初始化所有内容。手册在这个主题上非常混乱,通常引用类型或变量而不解释它们的来源或使用原因。我这样调用解析:

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仍然是零!所以我怀疑我没有正确地初始化某些东西,这导致它不知道从哪里获取输入。

最终编辑: 我将这个问题标记为关闭,因为我的原始问题已得到解答,并将新问题作为一个新问题重新打开。

1 个答案:

答案 0 :(得分:2)

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

%{
#define YYPARSE_PARAM yyscan_t scanner
#define YYLEX_PARAM scanner
%}

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

现在,如果YYSTYPEint(您的%union文件中没有YYSTYPE.y声明),那么您需要设置令牌只需说出.l

即可在*yylval = whatever;中获得价值