在野牛我有一个工会
%union
{
std::string* sval;
}
我想像这样使用它
在 Lex 中:
*(yylval->sval) = "ABCD";
而不是
yylval->sval = new std::string("ABCD");
轻松防止内存泄漏
但是我需要一些方法来分配一个 std::string 到 sval 开始。
我怎样才能做到这一点?
在野牛我有一个工会
%union
{
std::string* sval;
}
我想像这样使用它
在 Lex 中:
*(yylval->sval) = "ABCD";
而不是
yylval->sval = new std::string("ABCD");
轻松防止内存泄漏
但是我需要一些方法来分配一个 std::string 到 sval 开始。
我怎样才能做到这一点?
您不能安全地将类型与构造函数或析构函数(例如 std::string)放在一个联合中,因此这不起作用。
你可以做的是根本不使用 %union - 而是使用宏将 YYSTYPE 直接映射到其他类型:
%{
#define YYSTYPE std::string
%}
那么 yylval 将是那种类型(语法代码中的所有 $n 选项也是如此)
我不完全清楚你为什么要这样做,但我可以明白为什么你所拥有的东西不起作用。这是因为"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 代码中根本没有分配或释放(即使在主代码中也很少)。