Reputation: 5177
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?
Upvotes: 1
Views: 4250
Reputation: 882078
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 a const char *
, not a std::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:
std::string *strABCD = new std::string("ABCD");
in that section and then use:
yylval->sval = strABCD;
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:
std::string *strABCD = new std::string ("ABCD");
int main(...) {
// Do some stuff.
: : :
yyparse();
: : :
// Do some other stuff.
}
Bison parser source:
%{
extern std::string *strABCD;
%}
: : :
yylval->sval = strABCD;
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).
Upvotes: 0
Reputation: 2960
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:
%{
#define YYSTYPE std::string
%}
then yylval will be that type (as will all $n options in the grammar code)
Upvotes: 2