1

在野牛我有一个工会

%union
{
   std::string* sval;
}

我想像这样使用它

在 Lex 中:

*(yylval->sval) = "ABCD";

而不是

yylval->sval = new std::string("ABCD");

轻松防止内存泄漏

但是我需要一些方法来分配一个 std::string 到 sval 开始。

我怎样才能做到这一点?

4

2 回答 2

2

您不能安全地将类型与构造函数或析构函数(例如 std::string)放在一个联合中,因此这不起作用。

你可以做的是根本不使用 %union - 而是使用宏将 YYSTYPE 直接映射到其他类型:

%{
#define YYSTYPE std::string
%}

那么 yylval 将是那种类型(语法代码中的所有 $n 选项也是如此)

于 2009-08-10T23:13:04.523 回答
0

我不完全清楚你为什么要这样做,但我可以明白为什么你所拥有的东西不起作用。这是因为"ABCD"是一个const char *,而不是一个std::string

我知道 Yacc 的第一"%{ ... %}"部分允许您定义 Yacc 控制之外的 C 内容(并且 Bison 似乎具有类似的功能,基于它的向上兼容性声明和此处的文档2.1.1)。你为什么不放:

std::string *strABCD = new std::string("ABCD");

在该部分中,然后使用:

yylval->sval = strABCD;

以后每当您需要指向该字符串的指针时?

在我看来,这似乎是实现(我认为)你想要的最简单的方法。

如果您担心 Bison 解析器中的分配没有被释放(它们应该被释放),我的建议是不要在那里执行它们。您可以在调用之前设置字符串,yyparse()然后在返回后释放它。

更新:

这是我如何避免在 Bison 解析器中分配/释放该固定值的方法。将其设置为在程序期间存在的全局变量。

主要代码:

std::string *strABCD = new std::string ("ABCD");

int main(...) {
    // Do some stuff.
    : : :
    yyparse();
    : : :
    // Do some other stuff.
}

Bison 解析器源码:

%{
    extern std::string *strABCD;
%}
: : :
yylval->sval = strABCD;

这将返回指向您的 ABCD 字符串的固定指针,而在 Bison 代码中根本没有分配或释放(即使在主代码中也很少)。

于 2009-08-10T22:58:41.293 回答