1

我在按照步骤使我的 bison/flex 解析器可重入时遇到了麻烦。

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

void yyset_lval ( YYSTYPE * yylvalp , yyscan_t scanner );

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

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

弹性文件:

%{
#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 正在分配 astruct yyguts_t并将其清零。当我到达崩溃时,yy_cp 是一个空指针,实际上整个struct yyguts_t仍然是零!所以我怀疑我没有正确初始化某些东西,这导致它不知道从哪里获得输入。

最终编辑:我将把这个问题标记为已回答我的原始问题,并将新问题作为新问题重新打开。

4

1 回答 1

4

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

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

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

现在如果YYSTYPE是(您的文件int中没有%union或声明),那么您只需说YYSTYPE.y.l*yylval = whatever;

于 2012-09-18T01:00:35.160 回答