可重入 Bison 解析器。各个部分的代码是全局的吗?

Reentrant Bison parser. Is the code in the various sections global?

我正在使用 Bison 编写一个可重入解析器,得到了 SO 的大量帮助,但实际上并没有彻底测试可重入部分。我刚刚查看了 Bison 生成的 .tab.c 文件,惊讶地发现 %{ }% 或各种 %code 部分中的所有代码都是全局的。我原以为它们是 yyparse() 的局部变量。

我假设在解析器中本地使用的任何变量都必须使用 %parse-param 传递。
令人惊讶的是,%code 的 documentation 没有对 reEntrant 用法进行任何引用。

示例:

    %{
        mystruct *someStruct;
    }%

因此多次调用 yyparse() 将引用同一个变量(存储)。 为了解决这个问题,我必须创建一个

  %parse-param myStruct *someStruct;

然后使用可能从调用 yyparse() 的包装函数传递的附加参数修改 yyparse() 和 yyerror() 调用,使其真正是本地的。

我的观察是否正确?

是的,没错。

Bison 只确保它自己的代码不使用全局变量。不幸的是,除了将局部变量作为附加参数传递外,没有任何机制可以将局部变量添加到解析器中。即使您使用具有显式解析器上下文对象的推送解析器(我强烈推荐)也是如此。

如果您使用 C++ 接口,您会发现其他可能性,因为其中 API 生成的解析函数是可扩展 class.

的成员函数

就其价值而言,%code 文档没有提及可重入 API,我并不感到惊讶,因为 %code 部分的主要目的是保留声明和预处理器指令。 (特别是复制到生成的头文件中的 %code 部分。)但是文档错误修复总是受欢迎的(据我所知)。