本文介绍了用积分YYSTYPE使bison/flex解析器可重入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在按照步骤使我的bison/flex解析器进入最小程度的麻烦时,我遇到了麻烦.

I'm having trouble following the steps to make my bison/flex parser reentrant with a minimum amount of fuss.

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

The problem appears to be in the lexer. Since everything parser is re-entrant, I can no longer assign yylval directly. Instead, according to the Flex manual, I have to call this function:

void yyset_lval ( YYSTYPE * yylvalp , yyscan_t scanner );

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

But the problem is, YYSTYPE is an integral type. It isn't a dynamically allocated value, and it isn't an lvalue at all, so I can't pass a pointer to it! Am I missing something, and if not, how am I supposed to set yylvalue? I've never had this problem with a non-reentrant parser!

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

Update:Ok, I think I may have gotten past the integral type issue. Now the parser appears to crash because no input is set up, and I am not finding any documentation on how to tell the lexer where to read input from.

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;

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

I suspect I may not be initializing everything correctly for the parse. The manuals are very confusing on this subject, often referencing types or variable without explaining where they come from or why they are used. I am invoking the parse this way:

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仍为零.因此,我怀疑我没有正确初始化某物,这导致它不知道从何处获取输入.

From reading through the souce code, yylex_init is allocating a struct yyguts_t and zeroing it out. When I reach the crash, yy_cp is a null pointer, in fact the entire struct yyguts_t is still zero-ed out! So I suspect I am not initializing something properly, and that is resulting in it not knowing where to get input from.

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

Final edit:I'm going to mark this question as closed as my original question was answered, and re-open the new problem as a new question.

推荐答案

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

Normally to make a reentrant parser/scanner, you'll use %option bison-bridge in your .l file and %define api.pure in your .y file. This makes yylval an argument to yylex instead of a global variable. In addition, you need have:

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

.y文件顶部的

,将额外的scanner参数通过解析器传递给词法分析器.

in the top of your .y file to pass the extra scanner parameter through your parser to your lexer.

现在,如果YYSTYPEint(在.y文件中没有%unionYYSTYPE的声明),则只需在.l中说出*yylval = whatever;

Now if YYSTYPE is int (you have no %union or declaration of YYSTYPE in your .y file), then you'd set the token value in your .l by just saying *yylval = whatever;

这篇关于用积分YYSTYPE使bison/flex解析器可重入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-28 01:16