Finish implementation of per-type %destructor/%printer. Discussed

starting at
<http://lists.gnu.org/archive/html/bison-patches/2006-02/msg00064.html>
and
<http://lists.gnu.org/archive/html/bison-patches/2006-06/msg00091.html>.
* NEWS (2.3+): Add a description of this feature to the default
%destructor/%printer description.
* doc/bison.texinfo (Freeing Discarded Symbols): Likewise.
* src/symlist.c (symbol_list_destructor_set, symbol_list_printer_set):
Invoke semantic_type_destructor_set or semantic_type_printer_set when a
list node contains a semantic type.
* src/symtab.c, src/symtab.h: Extend with a table that associates
semantic types with their %destructor's and %printer's.
(semantic_type_from_uniqstr, semantic_type_get,
semantic_type_destructor_set, semantic_type_printer_set): New functions
composing the public interface of that table.
(symbol_destructor_get, symbol_destructor_location_get,
symbol_printer_get, symbol_printer_location_get):  If there's no
per-symbol %destructor/%printer, look up the per-type before trying
the default.
* tests/actions.at (Per-type %printer and %destructor): New test case.
* tests/input.at (Default %printer and %destructor redeclared):
Extend to check that multiple occurrences of %symbol-default in a
single %destructor/%printer declaration is an error.
(Per-type %printer and %destructor redeclared, Unused values with
per-type %destructor): New test cases.
This commit is contained in:
Joel E. Denny
2006-09-04 22:20:52 +00:00
parent 3be03b13e5
commit b2a0b7ca70
8 changed files with 484 additions and 45 deletions

View File

@@ -689,6 +689,132 @@ AT_CLEANUP
## ----------------------------------- ##
## Per-type %printer and %destructor. ##
## ----------------------------------- ##
AT_SETUP([Per-type %printer and %destructor])
AT_DATA_GRAMMAR([[input.y]],
[[%error-verbose
%debug
%{
# include <stdio.h>
# include <stdlib.h>
static void yyerror (const char *msg);
static int yylex (void);
# define USE(SYM)
%}
%union { int field0; int field1; int field2; }
%type <field0> start 'a' 'g'
%type <field1> 'e'
%type <field2> 'f'
%printer {
fprintf (yyoutput, "%%symbol-default/<field2>/e printer");
} %symbol-default 'e' <field2>
%destructor {
fprintf (stdout, "%%symbol-default/<field2>/e destructor.\n");
} %symbol-default 'e' <field2>
%type <field1> 'b'
%printer { fprintf (yyoutput, "<field1> printer"); } <field1>
%destructor { fprintf (stdout, "<field1> destructor.\n"); } <field1>
%type <field0> 'c'
%printer { fprintf (yyoutput, "'c' printer"); } 'c'
%destructor { fprintf (stdout, "'c' destructor.\n"); } 'c'
%type <field1> 'd'
%printer { fprintf (yyoutput, "'d' printer"); } 'd'
%destructor { fprintf (stdout, "'d' destructor.\n"); } 'd'
%%
start:
'a' 'b' 'c' 'd' 'e' 'f' 'g'
{
USE(($1, $2, $3, $4, $5, $6, $7));
$$ = 'S';
}
;
%%
static int
yylex (void)
{
static const char *input = "abcdef";
return *input++;
}
static void
yyerror (const char *msg)
{
fprintf (stderr, "%s\n", msg);
}
int
main (void)
{
yydebug = 1;
return yyparse ();
}
]])
AT_CHECK([bison -o input.c input.y])
AT_COMPILE([input])
AT_PARSER_CHECK([./input], 1,
[[%symbol-default/<field2>/e destructor.
%symbol-default/<field2>/e destructor.
'd' destructor.
'c' destructor.
<field1> destructor.
%symbol-default/<field2>/e destructor.
]],
[[Starting parse
Entering state 0
Reading a token: Next token is token 'a' (%symbol-default/<field2>/e printer)
Shifting token 'a' (%symbol-default/<field2>/e printer)
Entering state 1
Reading a token: Next token is token 'b' (<field1> printer)
Shifting token 'b' (<field1> printer)
Entering state 3
Reading a token: Next token is token 'c' ('c' printer)
Shifting token 'c' ('c' printer)
Entering state 5
Reading a token: Next token is token 'd' ('d' printer)
Shifting token 'd' ('d' printer)
Entering state 6
Reading a token: Next token is token 'e' (%symbol-default/<field2>/e printer)
Shifting token 'e' (%symbol-default/<field2>/e printer)
Entering state 7
Reading a token: Next token is token 'f' (%symbol-default/<field2>/e printer)
Shifting token 'f' (%symbol-default/<field2>/e printer)
Entering state 8
Reading a token: Now at end of input.
syntax error, unexpected $end, expecting 'g'
Error: popping token 'f' (%symbol-default/<field2>/e printer)
Stack now 0 1 3 5 6 7
Error: popping token 'e' (%symbol-default/<field2>/e printer)
Stack now 0 1 3 5 6
Error: popping token 'd' ('d' printer)
Stack now 0 1 3 5
Error: popping token 'c' ('c' printer)
Stack now 0 1 3
Error: popping token 'b' (<field1> printer)
Stack now 0 1
Error: popping token 'a' (%symbol-default/<field2>/e printer)
Stack now 0
Cleanup: discarding lookahead token $end ()
Stack now 0
]])
AT_CLEANUP
## ------------------------------------------------------------- ##
## Default %printer and %destructor for user-defined end token. ##
## ------------------------------------------------------------- ##

View File

@@ -175,8 +175,8 @@ AT_CLEANUP
AT_SETUP([Default %printer and %destructor redeclared])
AT_DATA([[input.y]],
[[%destructor { destroy ($$); } %symbol-default
%printer { destroy ($$); } %symbol-default
[[%destructor { destroy ($$); } %symbol-default %symbol-default
%printer { destroy ($$); } %symbol-default %symbol-default
%destructor { destroy ($$); } %symbol-default
%printer { destroy ($$); } %symbol-default
@@ -190,7 +190,11 @@ start: ;
]])
AT_CHECK([bison input.y], [1], [],
[[input.y:4.13-29: redeclaration for default %destructor
[[input.y:1.13-29: redeclaration for default %destructor
input.y:1.13-29: previous declaration
input.y:2.10-26: redeclaration for default %printer
input.y:2.10-26: previous declaration
input.y:4.13-29: redeclaration for default %destructor
input.y:1.13-29: previous declaration
input.y:5.10-26: redeclaration for default %printer
input.y:2.10-26: previous declaration
@@ -203,6 +207,49 @@ input.y:5.10-26: previous declaration
AT_CLEANUP
## ---------------------------------------------- ##
## Per-type %printer and %destructor redeclared. ##
## ---------------------------------------------- ##
AT_SETUP([Per-type %printer and %destructor redeclared])
AT_DATA([[input.y]],
[[%destructor { destroy ($$); } <field1> <field2>
%printer { destroy ($$); } <field1> <field2>
%destructor { destroy ($$); } <field1> <field1>
%printer { destroy ($$); } <field2> <field2>
%%
start: ;
%destructor { destroy ($$); } <field2> <field1>;
%printer { destroy ($$); } <field2> <field1>;
]])
AT_CHECK([bison input.y], [1], [],
[[input.y:4.13-29: %destructor redeclaration for <field1>
input.y:1.13-29: previous declaration
input.y:4.13-29: %destructor redeclaration for <field1>
input.y:4.13-29: previous declaration
input.y:5.10-26: %printer redeclaration for <field2>
input.y:2.10-26: previous declaration
input.y:5.10-26: %printer redeclaration for <field2>
input.y:5.10-26: previous declaration
input.y:11.13-29: %destructor redeclaration for <field1>
input.y:4.13-29: previous declaration
input.y:11.13-29: %destructor redeclaration for <field2>
input.y:1.13-29: previous declaration
input.y:12.10-26: %printer redeclaration for <field1>
input.y:2.10-26: previous declaration
input.y:12.10-26: %printer redeclaration for <field2>
input.y:5.10-26: previous declaration
]])
AT_CLEANUP
## ---------------------------------------- ##
## Unused values with default %destructor. ##
## ---------------------------------------- ##
@@ -227,6 +274,31 @@ input.y:6.6-8: warning: unset value: $$
AT_CLEANUP
## ----------------------------------------- ##
## Unused values with per-type %destructor. ##
## ----------------------------------------- ##
AT_SETUP([Unused values with per-type %destructor])
AT_DATA([[input.y]],
[[%destructor { destroy ($$); } <field1>
%type <field1> start end
%%
start: end end { $1; } ;
end: { } ;
]])
AT_CHECK([bison input.y], [0], [],
[[input.y:6.8-22: warning: unset value: $$
input.y:6.8-22: warning: unused value: $2
input.y:7.6-8: warning: unset value: $$
]])
AT_CLEANUP
## ---------------------- ##
## Incompatible Aliases. ##
## ---------------------- ##