Next: Printer Decl, Previous: Initial Action Decl, Up: Declarations [Contents][Index]
During error recovery (see Error Recovery), symbols already pushed
on the stack and tokens coming from the rest of the file are discarded
until the parser falls on its feet. If the parser runs out of memory,
or if it returns via YYABORT
or YYACCEPT
, all the
symbols on the stack must be discarded. Even if the parser succeeds, it
must discard the start symbol.
When discarded symbols convey heap based information, this memory is lost. While this behavior can be tolerable for batch parsers, such as in traditional compilers, it is unacceptable for programs like shells or protocol implementations that may parse and execute indefinitely.
The %destructor
directive defines code that is called when a
symbol is automatically discarded.
Invoke the braced code whenever the parser discards one of the
symbols. Within code, $$
(or $<tag>$
)
designates the semantic value associated with the discarded symbol, and
@$
designates its location. The additional parser parameters are
also available (see The Parser Function
yyparse
).
When a symbol is listed among symbols, its %destructor
is called a
per-symbol %destructor
.
You may also define a per-type %destructor
by listing a semantic type
tag among symbols.
In that case, the parser will invoke this code whenever it discards any
grammar symbol that has that semantic type tag unless that symbol has its own
per-symbol %destructor
.
Finally, you can define two different kinds of default %destructor
s.
(These default forms are experimental.
More user feedback will help to determine whether they should become permanent
features.)
You can place each of <*>
and <>
in the symbols list of
exactly one %destructor
declaration in your grammar file.
The parser will invoke the code associated with one of these whenever it
discards any user-defined grammar symbol that has no per-symbol and no per-type
%destructor
.
The parser uses the code for <*>
in the case of such a grammar
symbol for which you have formally declared a semantic type tag (%type
counts as such a declaration, but $<tag>$
does not).
The parser uses the code for <>
in the case of such a grammar
symbol that has no declared semantic type tag.
For example:
%union { char *string; } %token <string> STRING1 STRING2 %type <string> string1 string2 %union { char character; } %token <character> CHR %type <character> chr %token TAGLESS %destructor { } <character> %destructor { free ($$); } <*> %destructor { free ($$); printf ("%d", @$.first_line); } STRING1 string1 %destructor { printf ("Discarding tagless symbol.\n"); } <>
guarantees that, when the parser discards any user-defined symbol that has a
semantic type tag other than <character>
, it passes its semantic value
to free
by default.
However, when the parser discards a STRING1
or a string1
, it also
prints its line number to stdout
.
It performs only the second %destructor
in this case, so it invokes
free
only once.
Finally, the parser merely prints a message whenever it discards any symbol,
such as TAGLESS
, that has no semantic type tag.
A Bison-generated parser invokes the default %destructor
s only for
user-defined as opposed to Bison-defined symbols.
For example, the parser will not invoke either kind of default
%destructor
for the special Bison-defined symbols $accept
,
$undefined
, or $end
(see Bison Symbols),
none of which you can reference in your grammar.
It also will not invoke either for the error
token (see error), which is always defined by Bison regardless of whether you
reference it in your grammar.
However, it may invoke one of them for the end token (token 0) if you
redefine it from $end
to, for example, END
:
%token END 0
Finally, Bison will never invoke a %destructor
for an unreferenced
mid-rule semantic value (see Actions in Mid-Rule).
That is, Bison does not consider a mid-rule to have a semantic value if you
do not reference $$
in the mid-rule’s action or $n
(where n is the right-hand side symbol position of the mid-rule) in
any later action in that rule. However, if you do reference either, the
Bison-generated parser will invoke the <>
%destructor
whenever
it discards the mid-rule symbol.
Discarded symbols are the following:
parse
,
The parser can return immediately because of an explicit call to
YYABORT
or YYACCEPT
, or failed error recovery, or memory
exhaustion.
Right-hand side symbols of a rule that explicitly triggers a syntax
error via YYERROR
are not discarded automatically. As a rule
of thumb, destructors are invoked only when user actions cannot manage
the memory.
Next: Printer Decl, Previous: Initial Action Decl, Up: Declarations [Contents][Index]