可重入Bison解析器。各部分中的代码是全局的吗?
在SO的帮助下,我正在使用Bison编写一个可重入解析器,但实际上还没有彻底测试可重入部分。我刚刚查看了Bison生成的.tab.c文件,惊讶地发现%{}%或各种%code部分中的所有代码都是全局的。我希望它们是yyparse()的本地对象 我假定在解析器中本地使用的任何变量都必须使用%parse param进行传递。可重入Bison解析器。各部分中的代码是全局的吗?,bison,flex-lexer,yacc,Bison,Flex Lexer,Yacc,在SO的帮助下,我正在使用Bison编写一个可重入解析器,但实际上还没有彻底测试可重入部分。我刚刚查看了Bison生成的.tab.c文件,惊讶地发现%{}%或各种%code部分中的所有代码都是全局的。我希望它们是yyparse()的本地对象 我假定在解析器中本地使用的任何变量都必须使用%parse param进行传递。 令人惊讶的是,%代码没有引用可重入用法 例如: %{ mystruct *someStruct; }% 因此,yyparse()的多次调用将引用
令人惊讶的是,%代码没有引用可重入用法 例如:
%{
mystruct *someStruct;
}%
因此,yyparse()的多次调用将引用同一个变量(存储)。
为了解决这个问题,我必须创建一个
%parse-param myStruct *someStruct;
然后使用调用yyparse()的包装函数可能传递的附加参数修改yyparse()和yyerror()调用,使其真正是本地的
我的观察正确吗?是的,正确
Bison只确保自己的代码不使用全局变量。不幸的是,除了将局部变量作为附加参数传递之外,没有任何机制可以将它们添加到解析器中。即使您使用具有显式解析器上下文对象的推式解析器(我强烈建议使用),这也是正确的
如果你使用C++接口,你会发现其他的可能性,因为在那个API中,生成的解析函数是可扩展类的成员函数。
值得一提的是,
%code
文档没有提到可重入API,这并不奇怪,因为%code
部分的主要目的是保存声明和预处理器指令。(尤其是复制到生成的头文件中的%code
部分)但是文档错误修复总是受欢迎的(据我所知)