[antlr-interest] C target - initialization of return/scope structures
Anders.Karlsson at sybase.com
Anders.Karlsson at sybase.com
Thu May 20 00:08:46 PDT 2010
Hi,
Why don't you just use a smart pointer?
myrule
scope {auto_ptr<MyStruct> s;} //scoped POINTER
@init{ $myrule::s = auto_ptr<MyStruct>(new MyStruct());} //explicit
allocation using new
: rulegoeshere....;
or preferably boost:shared pointer
Thank you and kind regards,
Anders
Anders Karlsson | Staff SE II, Architect | Sybase Inc, Singapore, ( +65
6571 3125 | * anders.karlsson at sybase.com
-- It takes a tonne of fact to overcome an ounce of opinion
Cristian Târşoagă
<cristian.tarsoag
a at gmail.com> To
Sent by: antlr-interest
<antlr-interest-b <antlr-interest at antlr.org>
ounces at antlr.org> cc
Subject
05/20/2010 03:04 [antlr-interest] C target -
PM initialization of return/scope
structures
Hi Jim, that is not my problem, let me show you an example
I want to have a scoped value which is a structure, and my structure holds
some std::strings
struct MyStruct
{
std::string s1;
std::string s2;
};
//this is part of my grammar
myrule
scope {MyStruct s;} //scoped VALUE
@init{}
@after{}
: rulegoeshere....;
As you can see, there is no pointer here, the scoped variable is a 'value'.
The code generated by antlr creates a scoped wrapper structure that holds
MyStruct, something like:
ctx->pMyParser_myruleTop = pMyParser_myrulePush(ctx); // this will create a
wrapper for the scoped value by calling ANTLR3_MALLOC
the wrapper looks like this:
typedef struct MyParser_myrule_SCOPE_struct
{
void (ANTLR3_CDECL *free) (struct MyParser_myrule_SCOPE_struct *
frame);
MyStruct s;
}
As you can see my struct is inside this structure. The problem is that to
create the wrapper (see pMyParser_myrulePush above)
antlr calls ANTLR3_MALLOC (which does malloc of course).
THIS MEANS I'M GONNA GET A CRASH!
Why? because std::string is a c++ class, which HAS to be created/destroyed
using new/delete, not malloc/free.
That means, I cannot use a scoped VALUE, I have to use a scoped POINTER
instead, as suggested here:
http://www.mail-archive.com/il-antlr-interest@googlegroups.com/msg02614.html
Suggested Solution 1: local new/delete allocation/deallocation
------------------------------
-----------------------------------------------------------
So my rule will now look like this:
myrule
scope {MyStruct* s;} //scoped POINTER
@init{ $myrule::s = new MyStruct();} //explicit allocation using new
@after{ delete $myrule::s; } //explicit deallocation using delete
: rulegoeshere....;
Looks good? Well, I think not!
Because when the rule fails, the @after action is NOT called, and I'm gonna
get a nice memory leak.
Solution 1': the scoped wrapper has a member called free that can hold a
'deleter', but I couldn't find a way to set that.
Suggested Solution2: override antlr macros ANTLR3_MALLOC and ANTLR3_FREE
------------------------------------------------------------------------------------------------------------------------
Nice try, but ANTLR3_MALLOC is currently defined like this:
#define ANTLR3_MALLOC(request) malloc
((size_t)(request))
As you can see, the 'request' argument is a SIZE, not a type, which means
that if I want to override it to make it use 'new' instead of malloc, I
cannot use it.
>From the given size I cannot deduce the type (this could work the other
way
around if you change the define, to pass it the type you could get the
size,
and it could be possible to override the default way of antlr's
allocations/deallocations)
That is my problem and those are the options I have. Maybe with some
adjustment some of them will work, but right now, I'm not happy with any of
them: first one leaks, second one is not usable.
Maybe you have some hints for me :-)
Thanks a lot for your answer
Chris
List: http://www.antlr.org/mailman/listinfo/antlr-interest
Unsubscribe:
http://www.antlr.org/mailman/options/antlr-interest/your-email-address
More information about the antlr-interest
mailing list