]> git.saurik.com Git - bison.git/commitdiff
* NEWS: Instead of %union, you can define and use your own union type
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 9 Jul 2006 20:36:33 +0000 (20:36 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 9 Jul 2006 20:36:33 +0000 (20:36 +0000)
YYSTYPE if your grammar contains at least one <type> tag.
Your YYSTYPE need not be a macro; it can be a typedef.
* doc/bison.texinfo (Value Type, Multiple Types, Location Type):
(Union Decl, Decl Summary): Document this.
* data/glr.c (YYSTYPE): Implement this.
* data/glr.cc (YYSTYPE): Likewise.
* data/lalr1.cc (YYSTYPE): Likewise.
* data/yacc.c (YYSTYPE): Likewise.
* src/output.c (prepare): Output tag_seen_flag.
* src/parse-gram.y (declaration, grammar_declaration):
Use 'union_seen' rather than 'typed' to determine whether
%union has been seen, since grammars can now be typed without
%union.
(symbol_declaration, type.opt, symbol_def):
Keep track of whether a tag has been seen.
* src/reader.c (union_seen, tag_seen): New vars.
(typed): remove.
* src/reader.h (union_seen, tag_seen, typed): Likewise.
* src/scan-code.l (untyped_var_seen): New variable.
(handle_action_dollar): Adjust to above changes.
(handle_action_dollar, handle_action_at):
Improve overflow checking for outlandish numbers.
* tests/input.at (AT_CHECK_UNUSED_VALUES): Redo test to
avoid new diagnostics generated by above changes.
* tests/regression.at (YYSTYPE typedef): Add test to check
for type tags without %union.

14 files changed:
ChangeLog
NEWS
data/glr.c
data/glr.cc
data/lalr1.cc
data/yacc.c
doc/bison.texinfo
src/output.c
src/parse-gram.y
src/reader.c
src/reader.h
src/scan-code.l
tests/input.at
tests/regression.at

index 8a95c859bd27ed78a599eee64e8849c884ecb827..8aecae0b81deb2db5cf8e1ad8df84a60077949cc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+2006-07-09  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * NEWS: Instead of %union, you can define and use your own union type
+       YYSTYPE if your grammar contains at least one <type> tag.
+       Your YYSTYPE need not be a macro; it can be a typedef.
+       * doc/bison.texinfo (Value Type, Multiple Types, Location Type):
+       (Union Decl, Decl Summary): Document this.
+       * data/glr.c (YYSTYPE): Implement this.
+       * data/glr.cc (YYSTYPE): Likewise.
+       * data/lalr1.cc (YYSTYPE): Likewise.
+       * data/yacc.c (YYSTYPE): Likewise.
+       * src/output.c (prepare): Output tag_seen_flag.
+       * src/parse-gram.y (declaration, grammar_declaration):
+       Use 'union_seen' rather than 'typed' to determine whether
+       %union has been seen, since grammars can now be typed without
+       %union.
+       (symbol_declaration, type.opt, symbol_def):
+       Keep track of whether a tag has been seen.
+       * src/reader.c (union_seen, tag_seen): New vars.
+       (typed): remove.
+       * src/reader.h (union_seen, tag_seen, typed): Likewise.
+       * src/scan-code.l (untyped_var_seen): New variable.
+       (handle_action_dollar): Adjust to above changes.
+       (handle_action_dollar, handle_action_at):
+       Improve overflow checking for outlandish numbers.
+       * tests/input.at (AT_CHECK_UNUSED_VALUES): Redo test to
+       avoid new diagnostics generated by above changes.
+       * tests/regression.at (YYSTYPE typedef): Add test to check
+       for type tags without %union.
+
+       * src/symlist.c (symbol_list_length): Return int, not unsigned
+       int, since callers expect int.  This may need to get revisited
+       once we have proper integer overflow checking.
+
+       * src/scan-gram.h (gram_scanner_cursor): Remove decl, since this
+       object is now static.
+
+       * src/getargs.c (flags_argmatch): Return void, not int,
+       to pacify ./configure --enable-gcc-warnings.
+
+       * src/flex-scanner.h (STRING_FREE): Don't use FLEX_PREFIX (last_string)
+       since last_string is already defined to FLEX_PREFIX (last_string).
+
 2006-07-09  Akim Demaille  <akim@lrde.epita.fr>
 
        Implement --warnings/-W.
diff --git a/NEWS b/NEWS
index 0b6b23415253e32f8770d05a7fe86d364b45b658..d133f1937b0cee20c3cdd3611a7561b4692b20fe 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,12 @@ Bison News
 
 Changes in version 2.3+:
 
+* Instead of %union, you can define and use your own union type
+  YYSTYPE if your grammar contains at least one <type> tag.
+  Your YYSTYPE need not be a macro; it can be a typedef.
+  This change is for compatibility with other Yacc implementations,
+  and is required by POSIX.
+
 * Locations columns and lines start at 1.
   In accordance with the GNU Coding Standards and Emacs.
 
@@ -19,7 +25,7 @@ Changes in version 2.3+:
   `%{ ... %}' syntax.  To generate the pre-prologue, Bison concatenates all
   prologue blocks that you've declared before the first %union.  To generate
   the post-prologue, Bison concatenates all prologue blocks that you've
-  declared after the first %union.  
+  declared after the first %union.
 
   Previous releases of Bison inserted the pre-prologue into both the header
   file and the code file in all cases except for LALR(1) parsers in C.  In the
index 8da2048716cb8f9151075109e5dbdc7d790ff724..836df5032c72d646cea95dd866ca80b558d37aa5 100644 (file)
@@ -175,14 +175,15 @@ m4_define([b4_shared_declarations],
 
 b4_token_enums(b4_tokens)
 
-[#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+[#ifndef YYSTYPE
 ]m4_ifdef([b4_stype],
-[typedef union b4_union_name
-b4_user_stype
-       YYSTYPE;],
-[typedef int YYSTYPE;])[
-# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
+[[typedef union ]b4_union_name[
+]b4_user_stype[
+       YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1]],
+[m4_if(b4_tag_seen_flag, 0,
+[[typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1]])])[
 #endif
 
 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
index e742c03d17543721a2650a01ed7b3b412f33d554..59b9e3dd81b5478722d8e0837356d48a93610639 100644 (file)
@@ -288,7 +288,9 @@ namespace ]b4_namespace[
 [    union semantic_type
 b4_user_stype
        ;],
-[    typedef int semantic_type;])[
+[m4_if(b4_tag_seen_flag, 0,
+[[    typedef int semantic_type;]],
+[[    typedef YYSTYPE semantic_type;]])])[
 #else
     typedef YYSTYPE semantic_type;
 #endif
index 87b64fa17a2ed9f2aeae36806bff1ef7a95881d9..000cd0d1efee39aa44cde10fbddbfd889ae58ccb 100644 (file)
@@ -110,7 +110,9 @@ namespace ]b4_namespace[
 [    union semantic_type
 b4_user_stype
        ;],
-[    typedef int semantic_type;])[
+[m4_if(b4_tag_seen_flag, 0,
+[[    typedef int semantic_type;]],
+[[    typedef YYSTYPE semantic_type;]])])[
 #else
     typedef YYSTYPE semantic_type;
 #endif
index e297c643efe1990d2fe9248f5233c3a03e013a69..cdc6920390f36fb659c4fbbf4f4a2c1f06cc9200 100644 (file)
@@ -189,13 +189,15 @@ b4_token_enums_defines(b4_tokens)[
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 ]m4_ifdef([b4_stype],
-[[typedef union ]b4_union_name
-b4_user_stype
-       YYSTYPE;],
-[typedef int YYSTYPE;])[
+[[typedef union ]b4_union_name[
+]b4_user_stype[
+       YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1]],
+[m4_if(b4_tag_seen_flag, 0,
+[[typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1]])])[
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 ]b4_locations_if([#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
@@ -1499,13 +1501,15 @@ b4_token_enums_defines(b4_tokens)
 
 [#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 ]m4_ifdef([b4_stype],
-[[typedef union ]b4_union_name
-b4_user_stype
-       YYSTYPE;],
-[typedef int YYSTYPE;])[
+[[typedef union ]b4_union_name[
+]b4_user_stype[
+       YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1]],
+[m4_if(b4_tag_seen_flag, 0,
+[[typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1]])])[
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 ]b4_pure_if([],
index 0e181b8645368110362df462b28feeba8953730a..73afb8c30ea2b67321db3b0ffc82658e846a6d3a 100644 (file)
@@ -3092,7 +3092,8 @@ the semantic values of all language constructs.  This was true in the
 @acronym{RPN} and infix calculator examples (@pxref{RPN Calc, ,Reverse Polish
 Notation Calculator}).
 
-Bison's default is to use type @code{int} for all semantic values.  To
+Bison normally uses the type @code{int} for semantic values if your
+program uses the same data type for all language constructs.  To
 specify some other type, define @code{YYSTYPE} as a macro, like this:
 
 @example
@@ -3119,9 +3120,11 @@ requires you to do two things:
 
 @itemize @bullet
 @item
-Specify the entire collection of possible data types, with the
+Specify the entire collection of possible data types, either by using the
 @code{%union} Bison declaration (@pxref{Union Decl, ,The Collection of
-Value Types}).
+Value Types}), or by using a @code{typedef} or a @code{#define} to
+define @code{YYSTYPE} to be a union type whose member names are
+the type tags.
 
 @item
 Choose one of those types for each symbol (terminal or nonterminal) for
@@ -3500,7 +3503,7 @@ since all tokens and groupings always use the same type.
 
 You can specify the type of locations by defining a macro called
 @code{YYLTYPE}, just as you can specify the semantic value type by
-defining @code{YYSTYPE} (@pxref{Value Type}).
+defining a @code{YYSTYPE} macro (@pxref{Value Type}).
 When @code{YYLTYPE} is not defined, Bison uses a default structure type with
 four members:
 
@@ -3895,6 +3898,35 @@ only the first @code{%union} declaration can specify a tag.
 Note that, unlike making a @code{union} declaration in C, you need not write
 a semicolon after the closing brace.
 
+Instead of @code{%union}, you can define and use your own union type
+@code{YYSTYPE} if your grammar contains at least one
+@samp{<@var{type}>} tag.  For example, you can put the following into
+a header file @file{parser.h}:
+
+@example
+@group
+union YYSTYPE @{
+  double val;
+  symrec *tptr;
+@};
+typedef union YYSTYPE YYSTYPE;
+@end group
+@end example
+
+@noindent
+and then your grammar can use the following
+instead of @code{%union}:
+
+@example
+@group
+%@{
+#include "parser.h"
+%@}
+%type <val> expr
+%token <tptr> ID
+@end group
+@end example
+
 @node Type Decl
 @subsection Nonterminal Symbols
 @cindex declaring value types, nonterminals
@@ -4212,10 +4244,13 @@ names defined in the grammar as well as a few other declarations.
 If the parser output file is named @file{@var{name}.c} then this file
 is named @file{@var{name}.h}.
 
-Unless @code{YYSTYPE} is already defined as a macro, the output header
-declares @code{YYSTYPE}.  Therefore, if you are using a @code{%union}
+For C parsers, the output header declares @code{YYSTYPE} unless unless
+@code{YYSTYPE} is already defined as a macro or you have used a
+@code{<@var{type}>} tag without using @code{%union}.
+Therefore, if you are using a @code{%union}
 (@pxref{Multiple Types, ,More Than One Value Type}) with components that
 require other definitions, or if you have defined a @code{YYSTYPE} macro
+or type definition
 (@pxref{Value Type, ,Data Types of Semantic Values}), you need to
 arrange for these definitions to be propagated to all modules, e.g., by
 putting them in a prerequisite header that is included both by your
@@ -4227,7 +4262,7 @@ Parser}.
 
 If you have also used locations, the output header declares
 @code{YYLTYPE} and @code{yylloc} using a protocol similar to that of
-@code{YYSTYPE} and @code{yylval}.  @xref{Locations, ,Tracking
+the @code{YYSTYPE} macro and @code{yylval}.  @xref{Locations, ,Tracking
 Locations}.
 
 This output file is normally essential if you wish to put the definition
index 0d648770c2a4274700340ebb1e248536b0a0316a..534d82af08f1d6d44e6d85c5e763af841a838cd2 100644 (file)
@@ -590,6 +590,7 @@ prepare (void)
   MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
   MUSCLE_INSERT_BOOL ("pure_flag", pure_parser);
   MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
+  MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
   MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
 
   /* File names.  */
index 16ae62b8d555f76eff9f763be379da29b9b6ccf8..11fa187fcdf6ee28501abf7e6a820632410589ed 100644 (file)
@@ -57,7 +57,7 @@ static char const *char_name (char);
 static void add_param (char const *, char *, location);
 
 static symbol_class current_class = unknown_sym;
-static uniqstr current_type = 0;
+static uniqstr current_type = NULL;
 static symbol *current_lhs;
 static location current_lhs_location;
 static int current_prec = 0;
@@ -209,7 +209,7 @@ declaration:
   grammar_declaration
 | PROLOGUE
     {
-      prologue_augment (translate_code ($1, @1), @1, typed);
+      prologue_augment (translate_code ($1, @1), @1, union_seen);
     }
 | "%after-header" "{...}"
     {
@@ -322,7 +322,7 @@ grammar_declaration:
     {
       char const *body = $3;
 
-      if (typed)
+      if (union_seen)
        {
          /* Concatenate the union bodies, turning the first one's
             trailing '}' into '\n', and omitting the second one's '{'.  */
@@ -331,7 +331,7 @@ grammar_declaration:
          body++;
        }
 
-      typed = true;
+      union_seen = true;
       muscle_code_grow ("stype", body, @3);
     }
 ;
@@ -352,6 +352,7 @@ symbol_declaration:
     }
 | "%type" TYPE symbols.1
     {
+      tag_seen = true;
       symbol_list *list;
       for (list = $3; list; list = list->next)
        symbol_type_set (list->sym, $2, @2);
@@ -382,7 +383,7 @@ precedence_declarator:
 
 type.opt:
   /* Nothing. */ { current_type = NULL; }
-| TYPE           { current_type = $1; }
+| TYPE           { current_type = $1; tag_seen = true; }
 ;
 
 /* One or more nonterminals to be %typed. */
@@ -396,6 +397,7 @@ symbol_def:
   TYPE
      {
        current_type = $1;
+       tag_seen = true;
      }
 | id
      {
index aca5fb624adcf6e97a791843d12b5a55af276ce8..800ecc227876b0b060551ca804c3152a67e13c55 100644 (file)
@@ -45,7 +45,10 @@ static bool start_flag = false;
 merger_list *merge_functions;
 
 /* Was %union seen?  */
-bool typed = false;
+bool union_seen = false;
+
+/* Was a tag seen?  */
+bool tag_seen = false;
 
 /* Should rules have a default precedence?  */
 bool default_prec = true;
index 52c059c4ab162963eb7beff39f88f19090f4e127..43985965c4c41e893889c9731d04775e57d0969b 100644 (file)
@@ -59,7 +59,10 @@ void free_merger_functions (void);
 extern merger_list *merge_functions;
 
 /* Was %union seen?  */
-extern bool typed;
+extern bool union_seen;
+
+/* Was a tag seen?  */
+extern bool tag_seen;
 
 /* Should rules have a default precedence?  */
 extern bool default_prec;
index 703f2a6f345ff7822d19c0a56a846150030fba33..ec01f354a43e517a6aa6973557c05af03c82a64f 100644 (file)
@@ -55,6 +55,9 @@ static void handle_action_dollar (symbol_list *rule, char *cp,
 static void handle_action_at (symbol_list *rule, char *cp, location at_loc);
 static location the_location;
 static location *loc = &the_location;
+
+/* True if an untyped $$ or $n was seen.  */
+static bool untyped_var_seen;
 %}
  /* C and C++ comments in code. */
 %x SC_COMMENT SC_LINE_COMMENT
@@ -262,48 +265,62 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
        ++cp;
       *cp = '\0';
       ++cp;
+      if (untyped_var_seen)
+       complain_at (dollar_loc, _("explicit type given in untyped grammar"));
+      tag_seen = true;
     }
 
   if (*cp == '$')
     {
       if (!type_name)
        type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0);
-      if (!type_name && typed)
+
+      if (!type_name)
        {
-         if (rule->midrule_parent_rule)
-           complain_at (dollar_loc,
-                        _("$$ for the midrule at $%d of `%s' has no declared"
-                          " type"),
-                        rule->midrule_parent_rhs_index,
-                        effective_rule->sym->tag);
+         if (union_seen | tag_seen)
+           {
+             if (rule->midrule_parent_rule)
+               complain_at (dollar_loc,
+                            _("$$ for the midrule at $%d of `%s'"
+                              " has no declared type"),
+                            rule->midrule_parent_rhs_index,
+                            effective_rule->sym->tag);
+             else
+               complain_at (dollar_loc, _("$$ of `%s' has no declared type"),
+                            rule->sym->tag);
+           }
          else
-           complain_at (dollar_loc, _("$$ of `%s' has no declared type"),
-                        rule->sym->tag);
+           untyped_var_seen = true;
+         type_name = "";
        }
-      if (!type_name)
-       type_name = "";
+
       obstack_fgrow1 (&obstack_for_string,
                      "]b4_lhs_value([%s])[", type_name);
       rule->used = true;
     }
   else
     {
-      long int num;
-      set_errno (0);
-      num = strtol (cp, 0, 10);
-      if (INT_MIN <= num && num <= effective_rule_length && ! get_errno ())
+      long int num = strtol (cp, NULL, 10);
+
+      if (1 - INT_MAX + effective_rule_length <= num
+         && num <= effective_rule_length)
        {
          int n = num;
-         if (1-n > max_left_semantic_context)
-           max_left_semantic_context = 1-n;
-         if (!type_name && n > 0)
+         if (max_left_semantic_context < 1 - n)
+           max_left_semantic_context = 1 - n;
+         if (!type_name && 0 < n)
            type_name =
              symbol_list_n_type_name_get (effective_rule, dollar_loc, n);
-         if (!type_name && typed)
-           complain_at (dollar_loc, _("$%d of `%s' has no declared type"),
-                        n, effective_rule->sym->tag);
          if (!type_name)
-           type_name = "";
+           {
+             if (union_seen | tag_seen)
+               complain_at (dollar_loc, _("$%d of `%s' has no declared type"),
+                            n, effective_rule->sym->tag);
+             else
+               untyped_var_seen = true;
+             type_name = "";
+           }
+
          obstack_fgrow3 (&obstack_for_string,
                          "]b4_rhs_value(%d, %d, [%s])[",
                          effective_rule_length, n, type_name);
@@ -336,11 +353,10 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
     obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
   else
     {
-      long int num;
-      set_errno (0);
-      num = strtol (cp, 0, 10);
+      long int num = strtol (cp, NULL, 10);
 
-      if (INT_MIN <= num && num <= effective_rule_length && ! get_errno ())
+      if (1 - INT_MAX + effective_rule_length <= num
+         && num <= effective_rule_length)
        {
          int n = num;
          obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
@@ -356,9 +372,9 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
 | Initialize the scanner.  |
 `-------------------------*/
 
-/* Translate the dollars and ats in \a a, whose location is l.
-   Depending on the \a sc_context (SC_RULE_ACTION, SC_SYMBOL_ACTION,
-   INITIAL), the processing is different.  */
+/* Translate the dollars and ats in \a a, whose location is \a l.  The
+   translation is for \a rule, in the context \a sc_context
+   (SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL).  */
 
 static const char *
 translate_action (int sc_context, symbol_list *rule, const char *a, location l)
index df1ab704fa8aab9d34c8972bdc43b021b7128d18..223428f1695f85169016c00f0ee273203025bb86 100644 (file)
@@ -107,12 +107,12 @@ c: INT | INT { $]1[ } INT { } INT { };
 d: INT | INT { } INT { $]1[ } INT { };
 e: INT | INT { } INT {  } INT { $]1[ };
 f: INT | INT { } INT {  } INT { $]$[ = $]1[ + $]3[ + $]5[; };
-g: INT | INT { $]$[ } INT { $]$[ } INT { };
-h: INT | INT { $]$[ } INT { $]$[ = $]2[ } INT { };
+g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
+h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { };
 i: INT | INT INT { } { $]$[ = $]1[ + $]2[; };
 j: INT | INT INT { $<integer>$ = 1; } { $]$[ = $]1[ + $]2[; };
-k: INT | INT INT { $]$[; } { $]$[ = $]3[; } { };
-l: INT | INT { $]$[ = $]1[; } INT { $]$[ = $]2[ + $]3[; } INT { $]$[ = $]4[ + $]5[; };]]m4_ifval($1, [
+k: INT | INT INT { $<integer>$; } { $<integer>$ = $<integer>3; } { };
+l: INT | INT { $<integer>$ = $<integer>1; } INT { $<integer>$ = $<integer>2 + $<integer>3; } INT { $<integer>$ = $<integer>4 + $<integer>5; };]]m4_ifval($1, [
 _AT_UNUSED_VALUES_DECLARATIONS])
 )
 
@@ -131,22 +131,22 @@ input.y:14.10-35: warning: unused value: $]5[
 input.y:15.10-36: warning: unset value: $]$[
 input.y:15.10-36: warning: unused value: $]3[
 input.y:15.10-36: warning: unused value: $]5[
-input.y:17.10-38: warning: unset value: $]$[
-input.y:17.10-38: warning: unused value: $]1[
-input.y:17.10-38: warning: unused value: $]2[
-input.y:17.10-38: warning: unused value: $]3[
-input.y:17.10-38: warning: unused value: $]4[
-input.y:17.10-38: warning: unused value: $]5[
-input.y:18.10-43: warning: unset value: $]$[
-input.y:18.10-43: warning: unused value: $]1[
-input.y:18.10-43: warning: unused value: $]3[
-input.y:18.10-43: warning: unused value: $]4[
-input.y:18.10-43: warning: unused value: $]5[
+input.y:17.10-58: warning: unset value: $]$[
+input.y:17.10-58: warning: unused value: $]1[
+input.y:17.10-58: warning: unused value: $]2[
+input.y:17.10-58: warning: unused value: $]3[
+input.y:17.10-58: warning: unused value: $]4[
+input.y:17.10-58: warning: unused value: $]5[
+input.y:18.10-72: warning: unset value: $]$[
+input.y:18.10-72: warning: unused value: $]1[
+input.y:18.10-72: warning: unused value: $]3[
+input.y:18.10-72: warning: unused value: $]4[
+input.y:18.10-72: warning: unused value: $]5[
 input.y:20.10-55: warning: unused value: $]3[
-input.y:21.10-41: warning: unset value: $]$[
-input.y:21.10-41: warning: unused value: $]1[
-input.y:21.10-41: warning: unused value: $]2[
-input.y:21.10-41: warning: unused value: $]4[
+input.y:21.10-68: warning: unset value: $]$[
+input.y:21.10-68: warning: unused value: $]1[
+input.y:21.10-68: warning: unused value: $]2[
+input.y:21.10-68: warning: unused value: $]4[
 ]])])
 
 
index 7e22a90c003f5052997175c7c160592f3aa5f68c..70133797dbe5871d3330288b5cd87229023e7e56 100644 (file)
@@ -49,6 +49,33 @@ AT_CLEANUP
 
 
 
+## ----------------- ##
+## YYSTYPE typedef.  ##
+## ----------------- ##
+
+AT_SETUP([YYSTYPE typedef])
+
+AT_DATA_GRAMMAR([input.y],
+[[%{
+void yyerror (char const *);
+int yylex (void);
+typedef union { char const *val; } YYSTYPE;
+%}
+
+%type <val> program
+
+%%
+
+program: { $$ = ""; };
+]])
+
+AT_CHECK([bison -o input.c input.y])
+AT_COMPILE([input.o], [-c input.c])
+
+AT_CLEANUP
+
+
+
 ## ------------------------------------- ##
 ## Early token definitions with --yacc.  ##
 ## ------------------------------------- ##