[antlr-interest] C target - initialization of return/scope structures

Jim Idle jimi at temporal-wave.com
Thu May 20 06:17:25 PDT 2010


There is a macro to access the SCOPE_TOP(). 

Jim


> -----Original Message-----
> From: antlr-interest-bounces at antlr.org [mailto:antlr-interest-
> bounces at antlr.org] On Behalf Of Cristian Târºoagã
> Sent: Thursday, May 20, 2010 5:49 AM
> To: antlr-interest
> Subject: Re: [antlr-interest] C target - initialization of return/scope
> structures
> 
> Hi Mark,
> 
> thanks a lot, I think that is what I was looking for!
> once I'll be able to install a custom deleter, my problems are solved!
> allocation was not a problem even without using 'placement' new, but
> deletion was a problem indeed (only when the rule was failing, leaks
> could
> occur)
> 
> Honestly, I never thought to put something like this:
> ctx->pMyGrammarParser_GSTop->free = &free_MyStruct;
> in the @init action, I thought that maybe there is a general way to
> install
> the deleter, using a macro...I don't know...
> 
> But you're right, this WILL delete my pointers properly, THANKS!!   :-)
> 
>     Chris
> 
> 
> 
> 
> 
> 2010/5/20 Mark Wright <markwright at internode.on.net>
> 
> > On Thu, May 20, 2010 at 10:04:09AM +0300, Cristian Târşoagă wrote:
> > > 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.
> >
> > Hi Cristian,
> >
> > As Jim advised, you need to initialise it in @init().  As the memory
> has
> > already been allocated, the correct way to initialise it is to call
> the
> > constructor with placement operator new.
> >
> > And it is necessary to register your own free method to call the
> > destructor.
> >
> > grammar MyGrammar;
> >
> > options {
> >        language = C;
> > }
> >
> > scope GS {
> >  MyStruct s;
> > }
> >
> > @parser::includes {
> > #include <new>
> > #include "MyStruct.h"
> > }
> >
> > myrule
> > scope GS;
> > @init{
> >  new(&($GS::s))MyStruct;
> >  ctx->pMyGrammarParser_GSTop->free = &free_MyStruct;
> > }
> >        : 'foo'
> >        | 'bar'
> >        ;
> >
> > mystruct.h:
> > #include <string>
> > #include <antlr3.h>
> >
> > struct MyStruct
> > {
> >  std::string s1;
> >  std::string s2;
> > };
> >
> > extern "C" {
> >  void ANTLR3_CDECL free_MyStruct(struct
> MyGrammarParser_GS_SCOPE_struct
> > *scope);
> > }
> >
> > mystruct.cpp:
> > extern "C" {
> > void ANTLR3_CDECL free_MyStruct(struct
> MyGrammarParser_GS_SCOPE_struct
> > *scope)
> > {
> >  // Call the destructor
> >  (&(scope->s))->MyStruct::~MyStruct();
> > }
> > }
> >
> > Regards, Mark
> >
> > > 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 at 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
> > >
> >
> 
> 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