我无法按照步骤使我的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
仍然是零!所以我怀疑我没有正确地初始化某些东西,这导致它不知道从哪里获取输入。
最终编辑: 我将这个问题标记为关闭,因为我的原始问题已得到解答,并将新问题作为一个新问题重新打开。
答案 0 :(得分:2)
通常,要制作可重入的解析器/扫描程序,您将在%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;
中获得价值