mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-16 15:53:03 +00:00
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:
126
tests/actions.at
126
tests/actions.at
@@ -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. ##
|
||||
## ------------------------------------------------------------- ##
|
||||
|
||||
@@ -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. ##
|
||||
## ---------------------- ##
|
||||
|
||||
Reference in New Issue
Block a user