help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: %destructor


From: Hans Aberg
Subject: Re: %destructor
Date: Sat, 27 Sep 2014 00:23:37 +0200

> On 26 Sep 2014, at 21:58, Bob Rossi <address@hidden> wrote:
> 
> On Fri, Sep 26, 2014 at 03:37:18PM +0200, Hans Aberg wrote:

>>> The %destructor for result and result_list does not call free, but
>>> instead calls gdbmi_result_free. gdbmi_result_free free's the result
>>> (including the variable member of the result), and the result's next
>>> pointer, and so on.
>>> 
>>> Is it correct for me to call gdbmi_result_free($$) instead of free($$)?
>> 
>> The %destructor is for making C style cleanup during an error recovery: the 
>> Bison generated parser will then skip forward, bypassing any normal 
>> deallocations in the actions. So first write the parser in normal C style, 
>> with deallocators in each instance matching the allocator used in the 
>> actions. Then add %destructor if needed for the error recovery.
> 
> Unfortunately, this confused me more than clarified things.
> 
> What are the 'normal deallocations in the actions?' I only ever put
> allocations in the actions, never deallocations.

Then it will leak for everything that you do no deallocate during normal, 
error-free parsing.

> In the second sentence you mentioned I should write deallocators in each
> instance matching the allocator used in the actions. THEN add
> %destructor if needed for error recovery.
> 
> Where do I put deallocators in the bison generator parser, besides
> %destructor?

I am normally using C++, which is doing the cleanup, but let’s try C 
(pseudocode):

list:
   "[“ sequence[x] "]"    { $$ = $x; }
;

sequence:
   item[x]                  { $$ = make_list1($x); free($x); }
 | sequence[s] "," item[x]  { $$ = make_list($s, $x); free($s); free($x); }
;

In the first rule “list”, the pointer is reused, so no deallocation is needed. 
In the “sequence” rules, the functions make_list1() and make_list() are 
supposed to allocate a new list object, but not deallocate the pointers they 
get. So then the pointers $x and $s will not be used anymore, and must be 
deallocated in order to not leak.

> All of this side stepped the original question. Sorry if I was unclear.
> The question I was asking is, should I call free() or list_free() in
> the %destructor for a list.

The deallocator must always match the allocator used to create the element, 
otherwise the result is undefined. So if you have an allocator for a list that 
must list_free(), and that is what $$ holds, then this is the deallocator you 
must use. And this is only to prevent leaks during error recovery.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]