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

Cristian Târşoagă cristian.tarsoaga at gmail.com
Thu May 20 09:09:10 PDT 2010


Thank you!! :-)

  Chris

On Thu, May 20, 2010 at 4:17 PM, Jim Idle <jimi at temporal-wave.com> wrote:

> 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
>
>
>
>
> 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