[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