如何初始化 Bison 的 %union 值?
在 Bison 中,我有一个 union
%union
{
std::string* sval;
}
我想像这样使用它
在 Lex 中:
*(yylval->sval) = "ABCD";
而不是
yylval->sval = new std::string("ABCD");
轻松防止内存泄漏
但是我需要某种方法来将 std::string 分配给 sval 首先。
我怎样才能做到这一点?
In Bison I have a union
%union
{
std::string* sval;
}
And I want to use it like this
In Lex:
*(yylval->sval) = "ABCD";
Rather than
yylval->sval = new std::string("ABCD");
To prevent memory leaks easily
However I need some way to allocated a std::string to sval to begin with.
How can I do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法安全地将具有构造函数或析构函数的类型(例如 std::string)放入联合中,因此这不起作用。
你可以做的就是根本不使用 %union ——而是使用宏将 YYSTYPE 直接映射到其他类型:
然后 yylval 将是该类型(语法代码中的所有 $n 选项也是如此)
You can't safely put types with constructors or destructors (such as std::string) in a union, so this won't work.
What you can do instead is not use %union at all -- instead use a macro to map YYSTYPE directly to some other type:
then yylval will be that type (as will all $n options in the grammar code)
我不完全清楚你为什么要这样做,但我可以明白为什么你所拥有的不起作用。 这是因为
"ABCD"
是const char *
,而不是std::string
。我知道 Yacc 的第一个
"%{ ... %}"
部分允许您在 Yacc 的控制之外定义 C 内容(而且 Bison 似乎具有类似的功能,基于它的向上兼容性)声明和文档此处,2.1.1) 。 为什么不将: 放在该部分中,然后
在需要指向该字符串的指针时使用: ?
在我看来,这是实现(我认为)你想要的最简单的方法。
如果您担心 Bison 解析器内的分配未被释放(它们应该被释放),我的建议是不要在那里进行分配。 您可以在调用 yyparse() 之前设置字符串,然后在返回后释放它。
更新:
以下是我如何避免在 Bison 解析器中分配/释放该固定值的方法。 将其设置为在程序运行期间有效的全局变量。
主要代码:
Bison 解析器源代码:
返回指向 ABCD 字符串的固定指针,在 Bison 代码中根本没有分配或释放(甚至在主代码中也很少)。
I'm not entirely clear why you want to do this but I can see why what you have isn't working. It's because
"ABCD"
is aconst char *
, not astd::string
.I know with Yacc that the first
"%{ ... %}"
section allows you to define C stuff outside the control of Yacc (and it appears Bison has a similar feature, based on it's upward compatibility claim and the documentation here, 2.1.1). Why would you not put:in that section and then use:
later on whenever you needed a pointer to that string?
That seems to me to be the easiest way to achieve what (I think) you want.
If you're worried about allocations within the Bison parser not being freed (and they should be), my advice is to not do them in there. You can set up your string before calling
yyparse()
then free it after return.Update:
Here's how I'd do it to avoid allocating/freeing that fixed value within the Bison parser. Set it up as a global that lives for the duration of the program.
Main code:
Bison parser source:
That returns the fixed pointer to your ABCD string with no allocation or freeing in the Bison code at all (and precious little even in the main code).