help-bison
[Top][All Lists]
Advanced

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

%destructor


From: Bob Rossi
Subject: %destructor
Date: Thu, 25 Sep 2014 21:31:02 -0400
User-agent: Mutt/1.5.21 (2010-09-15)

Hi,

I'm writing a pure bison push parser in C.

I've unit tested the parser well, but now I'm starting to unit test
it when the parser has a syntax error. This has proved challenging.

The grammar is lined based. So from a top level, this sort of sums
up the grammar:

    output_list: output_list output {
    };

    output: output_variant NEWLINE {
          *gdbmi_output = $1;
    };

    output: error NEWLINE {
          yyerrok;
    };

I placed an error at the top level rule to be a 'catch all' to start.
It was unclear to me from the documentation if I should put,
  yyclearin ;
after yyerrok; in the function above. Does anyone know?


This parser is intended to run the lifetime of the program that is
using it, so it can't leak memory. I've thought of two strategies
for cleaning up memory.
    
The first is wrapping malloc and free, and if an error occurs, free the
pool of allocated memory. Since I don't currently have support for this,
and haven't investigated if Bison supports this, I'd like to not have
to follow this approach.

The second is to use Bison's %destructor support. Are there any known
limitations in Bison's support for %destructor in pure push parsers for C?

A secondary concern I had with %destructor is how it worked when lists
are used in the bison grammar. I'm concerned about a double free. For
instance,
    result_list: {
      $$ = NULL;
    };

    result_list: result_list COMMA result {
      $$ = append_gdbmi_result ($1, $3);
    };

    result: variable {
      $$ = gdbmi_result_alloc();
      $$->variable = $1;
    };

    variable: STRING_LITERAL {
      char *text = gdbmi_get_text(yyscanner);
      $$ = strdup(text);
    };

    %destructor { gdbmi_result_free($$); } result_list
    %destructor { gdbmi_result_free($$); } result
    %destructor { free($$); } variable

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($$)?

If so, does the bison language ensure that the variable destructor won't
also get called, which could result in a double free of the variable?
(Since gdbmi_result_free($$) will free the variable member too)

Thanks,
Bob Rossi



reply via email to

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