bison-patches
[Top][All Lists]
Advanced

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

Re: FYI: default %printer/%destructor


From: Joel E. Denny
Subject: Re: FYI: default %printer/%destructor
Date: Sat, 21 Oct 2006 06:03:41 -0400 (EDT)

On Thu, 14 Sep 2006, Joel E. Denny wrote:

> On Thu, 14 Sep 2006, Akim Demaille wrote:
> 
> > Or better yet (?), no %symbol-default, but:
> > 
> >   %printer { cerr << @$ << ": " << $$; } <*>
> 
> So, this means all symbols with types, right?  I was actually thinking of 
> this syntax before %symbol-default, but then I rejected it because I 
> couldn't figure out what to do about type-less symbols....
> 
> >   %printer { cerr << @$; } <->
> 
> I like this.  Small difference though: what about <!>?  In my mind, "!" = 
> "not", and it looks slightly odd, which is what we mean to imply, I think.
> 
> In the case of no %union and no <...> usage (that is, the user defines his 
> own YYSTYPE or uses the default int), are all symbols considered typed or 
> untyped?  That is, does <*> or <!> apply?  I'm leaning toward untyped and 
> <!>.  That way, when you refactor the last <...> out of your grammar, the 
> <!> %destructor won't suddenly quit applying to all other grammar symbols. 
> So maybe <*> means tagged symbols and <!> means tagless symbols (rather 
> than typed and untyped since someone might argue that all symbols are 
> typed with #define YYSTYPE int).

I committed the following.

Index: ChangeLog
===================================================================
RCS file: /sources/bison/bison/ChangeLog,v
retrieving revision 1.1593
diff -p -u -r1.1593 ChangeLog
--- ChangeLog   21 Oct 2006 04:52:43 -0000      1.1593
+++ ChangeLog   21 Oct 2006 09:58:21 -0000
@@ -1,5 +1,51 @@
 2006-10-21  Joel E. Denny  <address@hidden>
 
+       Split the default %destructor/%printer into two kinds: <*> and <!>.
+       Discussed starting at
+       <http://lists.gnu.org/archive/html/bison-patches/2006-09/msg00060.html>.
+       * NEWS (2.3a+): Mention.
+       * doc/bison.texinfo (Freeing Discarded Symbols): Document this and the
+       previous change today related to mid-rules.
+       (Bison Symbols): Remove %symbol-default and add <*> and <!>.
+       * src/parser-gram.y (PERCENT_SYMBOL_DEFAULT): Remove.
+       (TYPE_TAG_ANY): Add as <*>.
+       (TYPE_TAG_NONE): Add as <!>.
+       (generic_symlist_item): Remove RHS for %symbol-default and add RHS's
+       for <*> and <!>.
+       * src/scan-gram.l (PERCENT_SYMBOL_DEFAULT): Remove.
+       (TYPE_TAG_ANY, TYPE_TAG_NONE): Add.
+       * src/symlist.c (symbol_list_default_new): Split into tagged and
+       tagless versions.
+       (symbol_list_destructor_set, symbol_list_printer_set): Split
+       SYMLIST_DEFAULT case into SYMLIST_DEFAULT_TAGGED and
+       SYMLIST_DEFAULT_TAGLESS.
+       * src/symlist.h: Update symbol_list_default*_new prototypes.
+       (symbol_list.content_type): Split enum value SYMLIST_DEFAULT into
+       SYMLIST_DEFAULT_TAGGED and SYMLIST_DEFAULT_TAGLESS.
+       * src/symtab.c (default_destructor, default_destructor_location,
+       default_printer, default_printer_location): Split each into tagged and
+       tagless versions.
+       (symbol_destructor_get, symbol_destructor_location_get,
+       symbol_printer_get, symbol_printer_location_get): Implement tagged
+       default and tagless default cases.
+       (default_destructor_set, default_printer_set): Split each into tagged
+       and tagless versions.
+       * src/symtab.h: Update prototypes.
+       * tests/actions.at (Default %printer and %destructor): Rename to...
+       (Default tagless %printer and %destructor): ... this, and extend.
+       (Per-type %printer and %destructor): Rename to...
+       (Default tagged and per-type %printer and %destructor): ... this, and
+       extend.
+       (Default %printer and %destructor for user-defined end token): Extend.
+       (Default %printer and %destructor are not for error or $undefined):
+       Update.
+       (Default %printer and %destructor are not for $accept): Update.
+       (Default %printer and %destructor for mid-rule values): Extend.
+       * tests/input.at (Default %printer and %destructor redeclared): Extend.
+       (Unused values with default %destructor): Extend.
+
+2006-10-21  Joel E. Denny  <address@hidden>
+
        Don't apply the default %destructor/%printer to an unreferenced midrule
        value.  Mentioned at
        <http://lists.gnu.org/archive/html/bison-patches/2006-09/msg00104.html>.
Index: NEWS
===================================================================
RCS file: /sources/bison/bison/NEWS,v
retrieving revision 1.163
diff -p -u -r1.163 NEWS
--- NEWS        20 Oct 2006 22:10:50 -0000      1.163
+++ NEWS        21 Oct 2006 09:58:22 -0000
@@ -6,6 +6,25 @@ Changes in version 2.3a+ (????-??-??):
 * The -g and --graph options now output graphs in Graphviz DOT format,
   not VCG format.
 
+* Bison now recognizes two separate kinds of default %destructor's and
+  %printer's:
+
+    1. Place `<*>' in a %destructor/%printer symbol list to define a default
+       %destructor/%printer for all grammar symbols for which you have formally
+       declared semantic type tags.
+
+    2. Place `<!>' in a %destructor/%printer symbol list to define a default
+       %destructor/%printer for all grammar symbols without declared semantic
+       type tags.
+
+  Bison no longer supports the `%symbol-default' notation from Bison 2.3a.
+  `<*>' and `<!>' combined achieve the same effect with one exception: Bison no
+  longer applies any %destructor to a mid-rule value if that mid-rule value is
+  not actually ever referenced using either $$ or $n in a semantic action.
+
+  See the section `Freeing Discarded Symbols' in the Bison manual for further
+  details.
+
 * The Yacc prologue alternatives from Bison 2.3a have been rewritten as the
   following directives:
 
Index: doc/bison.texinfo
===================================================================
RCS file: /sources/bison/bison/doc/bison.texinfo,v
retrieving revision 1.210
diff -p -u -r1.210 bison.texinfo
--- doc/bison.texinfo   20 Oct 2006 22:10:50 -0000      1.210
+++ doc/bison.texinfo   21 Oct 2006 09:58:25 -0000
@@ -4236,8 +4236,8 @@ For instance, if your locations use a fi
 @subsection Freeing Discarded Symbols
 @cindex freeing discarded symbols
 @findex %destructor
address@hidden %symbol-default
-
address@hidden <*>
address@hidden <!>
 During error recovery (@pxref{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,
@@ -4265,21 +4265,26 @@ The Parser Function @code{yyparse}}).
 When a symbol is listed among @var{symbols}, its @code{%destructor} is called a
 per-symbol @code{%destructor}.
 You may also define a per-type @code{%destructor} by listing a semantic type
-among @var{symbols}.
+tag among @var{symbols}.
 In that case, the parser will invoke this @var{code} whenever it discards any
-grammar symbol that has that semantic type unless that symbol has its own
+grammar symbol that has that semantic type tag unless that symbol has its own
 per-symbol @code{%destructor}.
 
-Finally, you may define a default @code{%destructor} by placing
address@hidden in the @var{symbols} list of exactly one
address@hidden declaration in your grammar file.
-In that case, the parser will invoke the associated @var{code} whenever it
-discards any user-defined grammar symbol for which there is no per-type or
-per-symbol @code{%destructor}.
+Finally, you can define two different kinds of default @code{%destructor}s.
+You can place each of @code{<*>} and @code{<!>} in the @var{symbols} list of
+exactly one @code{%destructor} declaration in your grammar file.
+The parser will invoke the @var{code} associated with one of these whenever it
+discards any user-defined grammar symbol that has no per-symbol and no per-type
address@hidden
+The parser uses the @var{code} for @code{<*>} in the case of such a grammar
+symbol for which you have formally declared a semantic type tag (@code{%type}
+counts as such a declaration, but @code{$<tag>$} does not).
+The parser uses the @var{code} for @code{<!>} in the case of such a grammar
+symbol that has no declared semantic type tag.
 @end deffn
 
 @noindent
-For instance:
+For example:
 
 @smallexample
 %union @{ char *string; @}
@@ -4290,35 +4295,52 @@ For instance:
 %union @{ char character; @}
 %token <character> CHR
 %type  <character> chr
-%destructor @{ free ($$); @} %symbol-default
-%destructor @{ free ($$); printf ("%d", @@$.first_line); @} STRING1 string1
+%token TAGLESS
+
 %destructor @{ @} <character>
+%destructor @{ free ($$); @} <*>
+%destructor @{ free ($$); printf ("%d", @@$.first_line); @} STRING1 string1
+%destructor @{ printf ("Discarding tagless symbol.\n"); @} <!>
 @end smallexample
 
 @noindent
 guarantees that, when the parser discards any user-defined symbol that has a
 semantic type tag other than @code{<character>}, it passes its semantic value
-to @code{free}.
+to @code{free} by default.
 However, when the parser discards a @code{STRING1} or a @code{string1}, it also
 prints its line number to @code{stdout}.
 It performs only the second @code{%destructor} in this case, so it invokes
 @code{free} only once.
+Finally, the parser merely prints a message whenever it discards any symbol,
+such as @code{TAGLESS}, that has no semantic type tag.
 
-Notice that a Bison-generated parser invokes the default @code{%destructor}
-only for user-defined as opposed to Bison-defined symbols.
-For example, the parser will not invoke it for the special Bison-defined
-symbols @code{$accept}, @code{$undefined}, or @code{$end} (@pxref{Table of
-Symbols, ,Bison Symbols}), none of which you can reference in your grammar.
-It also will not invoke it for the @code{error} token (@pxref{Table of Symbols,
-,error}), which is always defined by Bison regardless of whether you reference
-it in your grammar.
-However, it will invoke it for the end token (token 0) if you redefine it from
address@hidden to, for example, @code{END}:
+A Bison-generated parser invokes the default @code{%destructor}s only for
+user-defined as opposed to Bison-defined symbols.
+For example, the parser will not invoke either kind of default
address@hidden for the special Bison-defined symbols @code{$accept},
address@hidden, or @code{$end} (@pxref{Table of Symbols, ,Bison Symbols}),
+none of which you can reference in your grammar.
+It also will not invoke either for the @code{error} token (@pxref{Table of
+Symbols, ,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 @code{$end} to, for example, @code{END}:
 
 @smallexample
 %token END 0
 @end smallexample
 
address@hidden actions in mid-rule
address@hidden mid-rule actions
+Finally, Bison will never invoke a @code{%destructor} for an unreferenced
+mid-rule semantic value (@pxref{Mid-Rule Actions,,Actions in Mid-Rule}).
+That is, Bison does not consider a mid-rule to have a semantic value if you do
+not reference @code{$$} in the mid-rule's action or @address@hidden (where
address@hidden is the RHS 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
address@hidden<!>} @code{%destructor} whenever it discards the mid-rule symbol.
+
 @ignore
 @noindent
 In the future, it may be possible to redefine the @code{error} token as a
@@ -8544,6 +8566,18 @@ Separates alternate rules for the same r
 @xref{Rules, ,Syntax of Grammar Rules}.
 @end deffn
 
address@hidden {Directive} <*>
+Used to define a default tagged @code{%destructor} or default tagged
address@hidden
address@hidden Decl, , Freeing Discarded Symbols}.
address@hidden deffn
+
address@hidden {Directive} <!>
+Used to define a default tagless @code{%destructor} or default tagless
address@hidden
address@hidden Decl, , Freeing Discarded Symbols}.
address@hidden deffn
+
 @deffn {Symbol} $accept
 The predefined nonterminal whose only rule is @samp{$accept: @var{start}
 $end}, where @var{start} is the start symbol.  @xref{Start Decl, , The
@@ -8776,11 +8810,6 @@ Bison declaration to specify the start s
 Start-Symbol}.
 @end deffn
 
address@hidden {Directive} %symbol-default
-Used to declare a default @code{%destructor} or default @code{%printer}.
address@hidden Decl, , Freeing Discarded Symbols}.
address@hidden deffn
-
 @deffn {Directive} %token
 Bison declaration to declare token(s) without specifying precedence.
 @xref{Token Decl, ,Token Type Names}.
Index: src/parse-gram.y
===================================================================
RCS file: /sources/bison/bison/src/parse-gram.y,v
retrieving revision 1.94
diff -p -u -r1.94 parse-gram.y
--- src/parse-gram.y    16 Oct 2006 05:25:36 -0000      1.94
+++ src/parse-gram.y    21 Oct 2006 09:58:26 -0000
@@ -116,8 +116,6 @@ static int current_prec = 0;
 %token PERCENT_TYPE        "%type"
 %token PERCENT_DESTRUCTOR  "%destructor"
 %token PERCENT_PRINTER     "%printer"
-%token PERCENT_SYMBOL_DEFAULT
-                           "%symbol-default"
 
 %token PERCENT_LEFT        "%left"
 %token PERCENT_RIGHT       "%right"
@@ -177,6 +175,8 @@ static int current_prec = 0;
 %token PROLOGUE        "%{...%}"
 %token SEMICOLON       ";"
 %token TYPE            "type"
+%token TYPE_TAG_ANY    "<*>"
+%token TYPE_TAG_NONE   "<!>"
 
 %type <character> CHAR
 %printer { fputs (char_name ($$), stderr); } CHAR
@@ -395,7 +395,8 @@ generic_symlist:
 generic_symlist_item:
   symbol            { $$ = symbol_list_sym_new ($1, @1); }
 | TYPE              { $$ = symbol_list_type_new ($1, @1); }
-| "%symbol-default" { $$ = symbol_list_default_new (@1); }
+| "<*>"             { $$ = symbol_list_default_tagged_new (@1); }
+| "<!>"             { $$ = symbol_list_default_tagless_new (@1); }
 ;
 
 /* One token definition.  */
Index: src/scan-gram.l
===================================================================
RCS file: /sources/bison/bison/src/scan-gram.l,v
retrieving revision 1.105
diff -p -u -r1.105 scan-gram.l
--- src/scan-gram.l     16 Oct 2006 05:25:36 -0000      1.105
+++ src/scan-gram.l     21 Oct 2006 09:58:27 -0000
@@ -194,7 +194,6 @@ splice       (\\[ \f\t\v]*\n)*
   "%right"                         return PERCENT_RIGHT;
   "%skeleton"                      return PERCENT_SKELETON;
   "%start"                         return PERCENT_START;
-  "%symbol-default"                 return PERCENT_SYMBOL_DEFAULT;
   "%term"                          return PERCENT_TOKEN;
   "%token"                         return PERCENT_TOKEN;
   "%token"[-_]"table"              return PERCENT_TOKEN_TABLE;
@@ -210,6 +209,8 @@ splice       (\\[ \f\t\v]*\n)*
   "="                     return EQUAL;
   "|"                     return PIPE;
   ";"                     return SEMICOLON;
+  "<*>"                   return TYPE_TAG_ANY;
+  "<!>"                   return TYPE_TAG_NONE;
 
   {id} {
     val->uniqstr = uniqstr_new (yytext);
Index: src/symlist.c
===================================================================
RCS file: /sources/bison/bison/src/symlist.c,v
retrieving revision 1.22
diff -p -u -r1.22 symlist.c
--- src/symlist.c       15 Sep 2006 16:34:48 -0000      1.22
+++ src/symlist.c       21 Oct 2006 09:58:27 -0000
@@ -74,16 +74,33 @@ symbol_list_type_new (uniqstr type_name,
 }
 
 
-/*----------------------------------------------------.
-| Create a list containing a %symbol-default at LOC.  |
-`----------------------------------------------------*/
+/*----------------------------------------.
+| Create a list containing a <*> at LOC.  |
+`----------------------------------------*/
 
 symbol_list *
-symbol_list_default_new (location loc)
+symbol_list_default_tagged_new (location loc)
 {
   symbol_list *res = xmalloc (sizeof *res);
 
-  res->content_type = SYMLIST_DEFAULT;
+  res->content_type = SYMLIST_DEFAULT_TAGGED;
+  res->location = loc;
+  res->next = NULL;
+
+  return res;
+}
+
+
+/*----------------------------------------.
+| Create a list containing a <!> at LOC.  |
+`----------------------------------------*/
+
+symbol_list *
+symbol_list_default_tagless_new (location loc)
+{
+  symbol_list *res = xmalloc (sizeof *res);
+
+  res->content_type = SYMLIST_DEFAULT_TAGLESS;
   res->location = loc;
   res->next = NULL;
 
@@ -215,8 +232,11 @@ symbol_list_destructor_set (symbol_list 
         semantic_type_destructor_set (
           semantic_type_get (node->content.type_name), destructor, loc);
         break;
-      case SYMLIST_DEFAULT:
-        default_destructor_set (destructor, loc);
+      case SYMLIST_DEFAULT_TAGGED:
+        default_tagged_destructor_set (destructor, loc);
+        break;
+      case SYMLIST_DEFAULT_TAGLESS:
+        default_tagless_destructor_set (destructor, loc);
         break;
     }
 }
@@ -233,8 +253,11 @@ symbol_list_printer_set (symbol_list *no
         semantic_type_printer_set (
           semantic_type_get (node->content.type_name), printer, loc);
         break;
-      case SYMLIST_DEFAULT:
-        default_printer_set (printer, loc);
+      case SYMLIST_DEFAULT_TAGGED:
+        default_tagged_printer_set (printer, loc);
+        break;
+      case SYMLIST_DEFAULT_TAGLESS:
+        default_tagless_printer_set (printer, loc);
         break;
     }
 }
Index: src/symlist.h
===================================================================
RCS file: /sources/bison/bison/src/symlist.h,v
retrieving revision 1.18
diff -p -u -r1.18 symlist.h
--- src/symlist.h       4 Sep 2006 19:29:29 -0000       1.18
+++ src/symlist.h       21 Oct 2006 09:58:27 -0000
@@ -29,10 +29,13 @@
 typedef struct symbol_list
 {
   /**
-   * Whether this node contains a symbol, a semantic type, or a
-   * \c \%symbol-default.
+   * Whether this node contains a symbol, a semantic type, a \c <*>, or a
+   * \c <!>.
    */
-  enum { SYMLIST_SYMBOL, SYMLIST_TYPE, SYMLIST_DEFAULT } content_type;
+  enum {
+    SYMLIST_SYMBOL, SYMLIST_TYPE,
+    SYMLIST_DEFAULT_TAGGED, SYMLIST_DEFAULT_TAGLESS
+  } content_type;
   union {
     /** The symbol or \c NULL iff <tt>node_type = SYMLIST_SYMBOL</tt>.  */
     symbol *sym;
@@ -76,8 +79,10 @@ symbol_list *symbol_list_sym_new (symbol
 /** Create a list containing \c type_name at \c loc.  */
 symbol_list *symbol_list_type_new (uniqstr type_name, location loc);
 
-/** Create a list containing a \c \%symbol-default at \c loc.  */
-symbol_list *symbol_list_default_new (location loc);
+/** Create a list containing a \c <*> at \c loc.  */
+symbol_list *symbol_list_default_tagged_new (location loc);
+/** Create a list containing a \c <!> at \c loc.  */
+symbol_list *symbol_list_default_tagless_new (location loc);
 
 /** Print this list.
 
Index: src/symtab.c
===================================================================
RCS file: /sources/bison/bison/src/symtab.c,v
retrieving revision 1.83
diff -p -u -r1.83 symtab.c
--- src/symtab.c        21 Oct 2006 04:52:43 -0000      1.83
+++ src/symtab.c        21 Oct 2006 09:58:27 -0000
@@ -41,14 +41,19 @@ symbol *accept = NULL;
 symbol *startsymbol = NULL;
 location startsymbol_location;
 
-/*-----------------------------------.
-| Default %destructor and %printer.  |
-`-----------------------------------*/
-
-static const char *default_destructor = NULL;
-static location default_destructor_location;
-static const char *default_printer = NULL;
-static location default_printer_location;
+/*---------------------------------------.
+| Default %destructor's and %printer's.  |
+`---------------------------------------*/
+
+static const char *default_tagged_destructor = NULL;
+static location default_tagged_destructor_location;
+static const char *default_tagless_destructor = NULL;
+static location default_tagless_destructor_location;
+
+static const char *default_tagged_printer = NULL;
+static location default_tagged_printer_location;
+static const char *default_tagless_printer = NULL;
+static location default_tagless_printer_location;
 
 /*---------------------------------.
 | Create a new symbol, named TAG.  |
@@ -220,10 +225,13 @@ symbol_destructor_get (symbol *sym)
         return type->destructor;
     }
 
-  /* Apply the default %destructor only to user-defined symbols.  */
+  /* Apply default %destructor's only to user-defined symbols.  */
   if (sym->tag[0] == '$' || sym == errtoken)
     return NULL;
-  return default_destructor;
+
+  if (sym->type_name)
+    return default_tagged_destructor;
+  return default_tagless_destructor;
 }
 
 /*---------------------------------------------------------------.
@@ -240,8 +248,9 @@ symbol_destructor_location_get (symbol *
       semantic_type *type = semantic_type_get (sym->type_name);
       if (type->destructor)
         return type->destructor_location;
+      return default_tagged_destructor_location;
     }
-  return default_destructor_location;
+  return default_tagless_destructor_location;
 }
 
 /*---------------------------------------------------------------.
@@ -300,7 +309,10 @@ symbol_printer_get (symbol *sym)
   /* Apply the default %printer only to user-defined symbols.  */
   if (sym->tag[0] == '$' || sym == errtoken)
     return NULL;
-  return default_printer;
+
+  if (sym->type_name)
+    return default_tagged_printer;
+  return default_tagless_printer;
 }
 
 /*------------------------------------------------------------.
@@ -317,8 +329,9 @@ symbol_printer_location_get (symbol *sym
       semantic_type *type = semantic_type_get (sym->type_name);
       if (type->printer)
         return type->printer_location;
+      return default_tagged_printer_location;
     }
-  return default_printer_location;
+  return default_tagless_printer_location;
 }
 
 
@@ -924,30 +937,58 @@ symbols_pack (void)
 }
 
 
-/*-----------------------------------.
-| Set default %destructor/%printer.  |
-`-----------------------------------*/
+/*--------------------------------------------------.
+| Set default tagged/tagless %destructor/%printer.  |
+`--------------------------------------------------*/
+
+void
+default_tagged_destructor_set (const char *destructor, location loc)
+{
+  if (default_tagged_destructor != NULL)
+    {
+      complain_at (loc, _("redeclaration for default tagged %%destructor"));
+      complain_at (default_tagged_destructor_location,
+                  _("previous declaration"));
+    }
+  default_tagged_destructor = destructor;
+  default_tagged_destructor_location = loc;
+}
+
+void
+default_tagless_destructor_set (const char *destructor, location loc)
+{
+  if (default_tagless_destructor != NULL)
+    {
+      complain_at (loc, _("redeclaration for default tagless %%destructor"));
+      complain_at (default_tagless_destructor_location,
+                  _("previous declaration"));
+    }
+  default_tagless_destructor = destructor;
+  default_tagless_destructor_location = loc;
+}
 
 void
-default_destructor_set (const char *destructor, location loc)
+default_tagged_printer_set (const char *printer, location loc)
 {
-  if (default_destructor != NULL)
+  if (default_tagged_printer != NULL)
     {
-      complain_at (loc, _("redeclaration for default %%destructor"));
-      complain_at (default_destructor_location, _("previous declaration"));
+      complain_at (loc, _("redeclaration for default tagged %%printer"));
+      complain_at (default_tagged_printer_location,
+                  _("previous declaration"));
     }
-  default_destructor = destructor;
-  default_destructor_location = loc;
+  default_tagged_printer = printer;
+  default_tagged_printer_location = loc;
 }
 
 void
-default_printer_set (const char *printer, location loc)
+default_tagless_printer_set (const char *printer, location loc)
 {
-  if (default_printer != NULL)
+  if (default_tagless_printer != NULL)
     {
-      complain_at (loc, _("redeclaration for default %%printer"));
-      complain_at (default_printer_location, _("previous declaration"));
+      complain_at (loc, _("redeclaration for default tagless %%printer"));
+      complain_at (default_tagless_printer_location,
+                  _("previous declaration"));
     }
-  default_printer = printer;
-  default_printer_location = loc;
+  default_tagless_printer = printer;
+  default_tagless_printer_location = loc;
 }
Index: src/symtab.h
===================================================================
RCS file: /sources/bison/bison/src/symtab.h,v
retrieving revision 1.65
diff -p -u -r1.65 symtab.h
--- src/symtab.h        4 Sep 2006 22:20:52 -0000       1.65
+++ src/symtab.h        21 Oct 2006 09:58:27 -0000
@@ -69,8 +69,8 @@ struct symbol
   /** Any \c \%destructor declared specifically for this symbol.
 
      Access this field only through <tt>symbol</tt>'s interface functions.  For
-     example, if <tt>symbol::destructor = NULL</tt>, the default
-     \c \%destructor or a per-type \c \%destructor might be appropriate, and
+     example, if <tt>symbol::destructor = NULL</tt>, a default \c \%destructor
+     or a per-type \c \%destructor might be appropriate, and
      \c symbol_destructor_get will compute the correct one.  */
   const char *destructor;
 
@@ -255,14 +255,18 @@ void symbols_check_defined (void);
 void symbols_pack (void);
 
 
-/*-----------------------------------.
-| Default %destructor and %printer.  |
-`-----------------------------------*/
-
-/** Set the default \c \%destructor.  */
-void default_destructor_set (const char *destructor, location loc);
-
-/** Set the default \c \%printer.  */
-void default_printer_set (const char *printer, location loc);
+/*---------------------------------------.
+| Default %destructor's and %printer's.  |
+`---------------------------------------*/
+
+/** Set the default \c \%destructor for tagged values.  */
+void default_tagged_destructor_set (const char *destructor, location loc);
+/** Set the default \c \%destructor for tagless values.  */
+void default_tagless_destructor_set (const char *destructor, location loc);
+
+/** Set the default \c \%printer for tagged values.  */
+void default_tagged_printer_set (const char *printer, location loc);
+/** Set the default \c \%printer for tagless values.  */
+void default_tagless_printer_set (const char *printer, location loc);
 
 #endif /* !SYMTAB_H_ */
Index: tests/actions.at
===================================================================
RCS file: /sources/bison/bison/tests/actions.at,v
retrieving revision 1.73
diff -p -u -r1.73 actions.at
--- tests/actions.at    21 Oct 2006 04:52:43 -0000      1.73
+++ tests/actions.at    21 Oct 2006 09:58:27 -0000
@@ -583,14 +583,14 @@ AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-pa
 
 
 
-## --------------------------------- ##
-## Default %printer and %destructor. ##
-## --------------------------------- ##
+## ----------------------------------------- ##
+## Default tagless %printer and %destructor. ##
+## ----------------------------------------- ##
 
 # Check that the right %printer and %destructor are called, that they're not
 # called for $end, and that $$ and @$ work correctly.
 
-AT_SETUP([Default %printer and %destructor])
+AT_SETUP([Default tagless %printer and %destructor])
 
 AT_DATA_GRAMMAR([[input.y]],
 [[%error-verbose
@@ -610,11 +610,15 @@ AT_DATA_GRAMMAR([[input.y]],
 %}
 
 %printer {
-  fprintf (yyoutput, "Default printer for '%c' @ %d", $$, @$.first_column);
-} %symbol-default
+  fprintf (yyoutput, "<*> printer should not be called.\n");
+} <*>
+
+%printer {
+  fprintf (yyoutput, "<!> printer for '%c' @ %d", $$, @$.first_column);
+} <!>
 %destructor {
-  fprintf (stdout, "Default destructor for '%c' @ %d.\n", $$, @$.first_column);
-} %symbol-default
+  fprintf (stdout, "<!> destructor for '%c' @ %d.\n", $$, @$.first_column);
+} <!>
 
 %printer {
   fprintf (yyoutput, "'b'/'c' printer for '%c' @ %d", $$, @$.first_column);
@@ -623,6 +627,10 @@ AT_DATA_GRAMMAR([[input.y]],
   fprintf (stdout, "'b'/'c' destructor for '%c' @ %d.\n", $$, @$.first_column);
 } 'b' 'c'
 
+%destructor {
+  fprintf (yyoutput, "<*> destructor should not be called.\n");
+} <*>
+
 %%
 
 start: 'a' 'b' 'c' 'd' 'e' { $$ = 'S'; USE(($1, $2, $3, $4, $5)); } ;
@@ -659,15 +667,15 @@ main (void)
 AT_CHECK([bison -o input.c input.y])
 AT_COMPILE([input])
 AT_PARSER_CHECK([./input], 1,
-[[Default destructor for 'd' @ 4.
+[[<!> destructor for 'd' @ 4.
 'b'/'c' destructor for 'c' @ 3.
 'b'/'c' destructor for 'b' @ 2.
-Default destructor for 'a' @ 1.
+<!> destructor for 'a' @ 1.
 ]],
 [[Starting parse
 Entering state 0
-Reading a token: Next token is token 'a' (1.1-1.1: Default printer for 'a' @ 1)
-Shifting token 'a' (1.1-1.1: Default printer for 'a' @ 1)
+Reading a token: Next token is token 'a' (1.1-1.1: <!> printer for 'a' @ 1)
+Shifting token 'a' (1.1-1.1: <!> printer for 'a' @ 1)
 Entering state 1
 Reading a token: Next token is token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2)
 Shifting token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2)
@@ -675,18 +683,18 @@ Entering state 3
 Reading a token: Next token is token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
 Shifting token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
 Entering state 5
-Reading a token: Next token is token 'd' (1.4-1.4: Default printer for 'd' @ 4)
-Shifting token 'd' (1.4-1.4: Default printer for 'd' @ 4)
+Reading a token: Next token is token 'd' (1.4-1.4: <!> printer for 'd' @ 4)
+Shifting token 'd' (1.4-1.4: <!> printer for 'd' @ 4)
 Entering state 6
 Reading a token: Now at end of input.
 syntax error, unexpected $end, expecting 'e'
-Error: popping token 'd' (1.4-1.4: Default printer for 'd' @ 4)
+Error: popping token 'd' (1.4-1.4: <!> printer for 'd' @ 4)
 Stack now 0 1 3 5
 Error: popping token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3)
 Stack now 0 1 3
 Error: popping token 'b' (1.2-1.2: 'b'/'c' printer for 'b' @ 2)
 Stack now 0 1
-Error: popping token 'a' (1.1-1.1: Default printer for 'a' @ 1)
+Error: popping token 'a' (1.1-1.1: <!> printer for 'a' @ 1)
 Stack now 0
 Cleanup: discarding lookahead token $end (1.5-1.5: )
 Stack now 0
@@ -696,11 +704,11 @@ AT_CLEANUP
 
 
 
-## ----------------------------------- ##
-## Per-type %printer and %destructor.  ##
-## ----------------------------------- ##
+## ------------------------------------------------------ ##
+## Default tagged and per-type %printer and %destructor.  ##
+## ------------------------------------------------------ ##
 
-AT_SETUP([Per-type %printer and %destructor])
+AT_SETUP([Default tagged and per-type %printer and %destructor])
 
 AT_DATA_GRAMMAR([[input.y]],
 [[%error-verbose
@@ -714,16 +722,20 @@ AT_DATA_GRAMMAR([[input.y]],
 # define USE(SYM)
 %}
 
+%printer {
+  fprintf (yyoutput, "<!> printer should not be called.\n");
+} <!>
+
 %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>
+  fprintf (yyoutput, "<*>/<field2>/e printer");
+} <*> 'e' <field2>
 %destructor {
-  fprintf (stdout, "%%symbol-default/<field2>/e destructor.\n");
-} %symbol-default 'e' <field2>
+  fprintf (stdout, "<*>/<field2>/e destructor.\n");
+} <*> 'e' <field2>
 
 %type <field1> 'b'
 %printer { fprintf (yyoutput, "<field1> printer"); } <field1>
@@ -737,6 +749,10 @@ AT_DATA_GRAMMAR([[input.y]],
 %printer { fprintf (yyoutput, "'d' printer"); } 'd'
 %destructor { fprintf (stdout, "'d' destructor.\n"); } 'd'
 
+%destructor {
+  fprintf (yyoutput, "<!> destructor should not be called.\n");
+} <!>
+
 %%
 
 start:
@@ -776,17 +792,17 @@ main (void)
 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.
+[[<*>/<field2>/e destructor.
+<*>/<field2>/e destructor.
 'd' destructor.
 'c' destructor.
 <field1> destructor.
-%symbol-default/<field2>/e destructor.
+<*>/<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)
+Reading a token: Next token is token 'a' (<*>/<field2>/e printer)
+Shifting token 'a' (<*>/<field2>/e printer)
 Entering state 1
 Reading a token: Next token is token 'b' (<field1> printer)
 Shifting token 'b' (<field1> printer)
@@ -797,17 +813,17 @@ 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)
+Reading a token: Next token is token 'e' (<*>/<field2>/e printer)
+Shifting token 'e' (<*>/<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)
+Reading a token: Next token is token 'f' (<*>/<field2>/e printer)
+Shifting token 'f' (<*>/<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)
+Error: popping token 'f' (<*>/<field2>/e printer)
 Stack now 0 1 3 5 6 7
-Error: popping token 'e' (%symbol-default/<field2>/e printer)
+Error: popping token 'e' (<*>/<field2>/e printer)
 Stack now 0 1 3 5 6
 Error: popping token 'd' ('d' printer)
 Stack now 0 1 3 5
@@ -815,7 +831,7 @@ 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)
+Error: popping token 'a' (<*>/<field2>/e printer)
 Stack now 0
 Cleanup: discarding lookahead token $end ()
 Stack now 0
@@ -826,12 +842,19 @@ AT_CLEANUP
 
 
 ## ------------------------------------------------------------- ##
-## Default %printer and %destructor for user-defined end token. ##
+## Default %printer and %destructor for user-defined end token.  ##
 ## ------------------------------------------------------------- ##
 
 AT_SETUP([Default %printer and %destructor for user-defined end token])
 
-AT_DATA_GRAMMAR([[input.y]],
+# _AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(TYPED)
+# -----------------------------------------------------------------------------
+m4_define([_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN],
+[m4_if($1, 0,
+  [m4_pushdef([kind], [!]) m4_pushdef([not_kind], [*])],
+  [m4_pushdef([kind], [*]) m4_pushdef([not_kind], [!])])
+
+AT_DATA_GRAMMAR([[input]]$1[[.y]],
 [[%error-verbose
 %debug
 %locations
@@ -848,13 +871,26 @@ AT_DATA_GRAMMAR([[input.y]],
 # define USE(SYM)
 %}
 
+%destructor {
+  fprintf (yyoutput, "<]]not_kind[[> destructor should not be called.\n");
+} <]]not_kind[[>
+
 %token END 0
 %printer {
-  fprintf (yyoutput, "Default printer for '%c' @ %d", $$, @$.first_column);
-} %symbol-default
+  fprintf (yyoutput, "<]]kind[[> for '%c' @ %d", $$, @$.first_column);
+} <]]kind[[>
 %destructor {
-  fprintf (stdout, "Default destructor for '%c' @ %d.\n", $$, @$.first_column);
-} %symbol-default
+  fprintf (stdout, "<]]kind[[> for '%c' @ %d.\n", $$, @$.first_column);
+} <]]kind[[>
+
+%printer {
+  fprintf (yyoutput, "<]]not_kind[[> printer should not be called.\n");
+} <]]not_kind[[>
+
+]]m4_if($1, 0, [[[
+]]],
+[[[%union { char tag; }
+%type <tag> start END]]])[[
 
 %%
 
@@ -868,7 +904,7 @@ yylex (void)
   static int called;
   if (called++)
     abort ();
-  yylval = 'E';
+  yylval]]m4_if($1, 0,, [[[.tag]]])[[ = 'E';
   yylloc.first_line = yylloc.last_line = 1;
   yylloc.first_column = yylloc.last_column = 1;
   return 0;
@@ -888,26 +924,33 @@ main (void)
 }
 ]])
 
-AT_CHECK([bison -o input.c input.y])
-AT_COMPILE([input])
-AT_PARSER_CHECK([./input], 0,
-[[Default destructor for 'E' @ 1.
-Default destructor for 'S' @ 1.
+AT_CHECK([bison -o input$1.c input$1.y])
+AT_COMPILE([input$1])
+AT_PARSER_CHECK([./input$1], 0,
+[[<]]kind[[> for 'E' @ 1.
+<]]kind[[> for 'S' @ 1.
 ]],
 [[Starting parse
 Entering state 0
-Reducing stack by rule 1 (line 35):
--> $$ = nterm start (1.1-1.1: Default printer for 'S' @ 1)
+Reducing stack by rule 1 (line 46):
+-> $$ = nterm start (1.1-1.1: <]]kind[[> for 'S' @ 1)
 Stack now 0
 Entering state 1
 Reading a token: Now at end of input.
-Shifting token END (1.1-1.1: Default printer for 'E' @ 1)
+Shifting token END (1.1-1.1: <]]kind[[> for 'E' @ 1)
 Entering state 2
 Stack now 0 1 2
-Cleanup: popping token END (1.1-1.1: Default printer for 'E' @ 1)
-Cleanup: popping nterm start (1.1-1.1: Default printer for 'S' @ 1)
+Cleanup: popping token END (1.1-1.1: <]]kind[[> for 'E' @ 1)
+Cleanup: popping nterm start (1.1-1.1: <]]kind[[> for 'S' @ 1)
 ]])
 
+m4_popdef([kind])
+m4_popdef([not_kind])
+])
+
+_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(0)
+_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(1)
+
 AT_CLEANUP
 
 
@@ -940,10 +983,10 @@ AT_DATA_GRAMMAR([[input.y]],
 
 %printer {
   fprintf (yyoutput, "'%c'", $$);
-} %symbol-default
+} <!> <*>
 %destructor {
   fprintf (stderr, "DESTROY '%c'\n", $$);
-} %symbol-default
+} <!> <*>
 
 %%
 
@@ -1055,11 +1098,11 @@ AT_DATA_GRAMMAR([[input.y]],
 %printer {
   char chr = $$;
   fprintf (yyoutput, "'%c'", chr);
-} %symbol-default
+} <!> <*>
 %destructor {
   char chr = $$;
   fprintf (stderr, "DESTROY '%c'\n", chr);
-} %symbol-default
+} <!> <*>
 
 %union { char chr; }
 %type <chr> start
@@ -1119,8 +1162,10 @@ AT_DATA_GRAMMAR([[input.y]],
 # define YY_LOCATION_PRINT(File, Loc)
 %}
 
-%printer { fprintf (yyoutput, "%d", @$); } %symbol-default
-%destructor { fprintf (stderr, "DESTROY %d\n", @$); } %symbol-default
+%printer { fprintf (yyoutput, "%d", @$); } <!>
+%destructor { fprintf (stderr, "DESTROY %d\n", @$); } <!>
+%printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
+%destructor { fprintf (yyoutput, "<*> destructor should not be called"); } <*>
 
 %%
 
@@ -1159,27 +1204,27 @@ main (void)
 ]])
 
 AT_CHECK([bison -o input.c input.y], 0,,
-[[input.y:31.3-23: warning: unset value: $$
-input.y:28.3-33.37: warning: unused value: $3
+[[input.y:33.3-23: warning: unset value: $$
+input.y:30.3-35.37: warning: unused value: $3
 ]])
 
 AT_COMPILE([input])
 AT_PARSER_CHECK([./input], 1,,
 [[Starting parse
 Entering state 0
-Reducing stack by rule 1 (line 28):
+Reducing stack by rule 1 (line 30):
 -> $$ = nterm address@hidden (: )
 Stack now 0
 Entering state 2
-Reducing stack by rule 2 (line 29):
+Reducing stack by rule 2 (line 31):
 -> $$ = nterm @2 (: 2)
 Stack now 0 2
 Entering state 4
-Reducing stack by rule 3 (line 30):
+Reducing stack by rule 3 (line 32):
 -> $$ = nterm @3 (: 3)
 Stack now 0 2 4
 Entering state 5
-Reducing stack by rule 4 (line 31):
+Reducing stack by rule 4 (line 33):
 -> $$ = nterm @4 (: 4)
 Stack now 0 2 4 5
 Entering state 6
Index: tests/input.at
===================================================================
RCS file: /sources/bison/bison/tests/input.at,v
retrieving revision 1.59
diff -p -u -r1.59 input.at
--- tests/input.at      21 Oct 2006 02:31:50 -0000      1.59
+++ tests/input.at      21 Oct 2006 09:58:27 -0000
@@ -178,33 +178,54 @@ AT_CLEANUP
 AT_SETUP([Default %printer and %destructor redeclared])
 
 AT_DATA([[input.y]],
-[[%destructor { destroy ($$); } %symbol-default %symbol-default
-%printer { destroy ($$); } %symbol-default %symbol-default
+[[%destructor { destroy ($$); } <*> <*>
+%printer { destroy ($$); } <*> <*>
 
-%destructor { destroy ($$); } %symbol-default
-%printer { destroy ($$); } %symbol-default
+%destructor { destroy ($$); } <*>
+%printer { destroy ($$); } <*>
+
+%destructor { destroy ($$); } <!> <!>
+%printer { destroy ($$); } <!> <!>
+
+%destructor { destroy ($$); } <!>
+%printer { destroy ($$); } <!>
 
 %%
 
 start: ;
 
-%destructor { destroy ($$); } %symbol-default;
-%printer { destroy ($$); } %symbol-default;
+%destructor { destroy ($$); } <*>;
+%printer { destroy ($$); } <*>;
+
+%destructor { destroy ($$); } <!>;
+%printer { destroy ($$); } <!>;
 ]])
 
 AT_CHECK([bison input.y], [1], [],
-[[input.y:1.13-29: redeclaration for default %destructor
+[[input.y:1.13-29: redeclaration for default tagged %destructor
 input.y:1.13-29: previous declaration
-input.y:2.10-26: redeclaration for default %printer
+input.y:2.10-26: redeclaration for default tagged %printer
 input.y:2.10-26: previous declaration
-input.y:4.13-29: redeclaration for default %destructor
+input.y:4.13-29: redeclaration for default tagged %destructor
 input.y:1.13-29: previous declaration
-input.y:5.10-26: redeclaration for default %printer
+input.y:5.10-26: redeclaration for default tagged %printer
 input.y:2.10-26: previous declaration
-input.y:11.13-29: redeclaration for default %destructor
+input.y:7.13-29: redeclaration for default tagless %destructor
+input.y:7.13-29: previous declaration
+input.y:8.10-26: redeclaration for default tagless %printer
+input.y:8.10-26: previous declaration
+input.y:10.13-29: redeclaration for default tagless %destructor
+input.y:7.13-29: previous declaration
+input.y:11.10-26: redeclaration for default tagless %printer
+input.y:8.10-26: previous declaration
+input.y:17.13-29: redeclaration for default tagged %destructor
 input.y:4.13-29: previous declaration
-input.y:12.10-26: redeclaration for default %printer
+input.y:18.10-26: redeclaration for default tagged %printer
 input.y:5.10-26: previous declaration
+input.y:20.13-29: redeclaration for default tagless %destructor
+input.y:10.13-29: previous declaration
+input.y:21.10-26: redeclaration for default tagless %printer
+input.y:11.10-26: previous declaration
 ]])
 
 AT_CLEANUP
@@ -260,18 +281,36 @@ AT_CLEANUP
 AT_SETUP([Unused values with default %destructor])
 
 AT_DATA([[input.y]],
-[[%destructor { destroy ($$); } %symbol-default
+[[%destructor { destroy ($$); } <!>
+%type <tag> tagged
 
 %%
 
-start: end end { $1; } ;
-end: { }  ;
+start: end end tagged tagged { $<tag>1; $3; } ;
+end: { } ;
+tagged: { } ;
+]])
+
+AT_CHECK([bison input.y], [0], [],
+[[input.y:6.8-45: warning: unset value: $$
+input.y:6.8-45: warning: unused value: $2
+input.y:7.6-8: warning: unset value: $$
+]])
+
+AT_DATA([[input.y]],
+[[%destructor { destroy ($$); } <*>
+%type <tag> tagged
+
+%%
+
+start: end end tagged tagged { $<tag>1; $3; } ;
+end: { } ;
+tagged: { } ;
 ]])
 
 AT_CHECK([bison input.y], [0], [],
-[[input.y:5.8-22: warning: unset value: $$
-input.y:5.8-22: warning: unused value: $2
-input.y:6.6-8: warning: unset value: $$
+[[input.y:6.8-45: warning: unused value: $4
+input.y:8.9-11: warning: unset value: $$
 ]])
 
 AT_CLEANUP




reply via email to

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