【问题标题】:Making bison/flex parser reentrant with integral YYSTYPE使用积分 YYSTYPE 使 bison/flex 解析器可重入
【发布时间】:2012-09-17 23:06:25
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: bison flex-lexer reentrancy


    【解决方案1】:

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

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

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

    现在如果YYSTYPEint(您的.y 文件中没有%unionYYSTYPE 声明),那么您只需说@ 即可在.l 中设置令牌值987654336@

    【讨论】:

    • 是的,错字——应该是*yylval
    猜你喜欢
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多