]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
* src/scan-gram.l: Remove unused declaration of last_string_1 so the
[bison.git] / src / parse-gram.y
index 5dec642d666a2149c2832cde4dfc9d3a63e226be..f45b323ca5e18c9a8ee380bde2505d2011289185 100644 (file)
@@ -1,6 +1,6 @@
 %{/* Bison Grammar Parser                             -*- C -*-
 
 %{/* Bison Grammar Parser                             -*- C -*-
 
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307  USA
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301  USA
 */
 
 */
 
+#include <config.h>
 #include "system.h"
 
 #include "complain.h"
 #include "system.h"
 
 #include "complain.h"
 #include "getargs.h"
 #include "gram.h"
 #include "muscle_tab.h"
 #include "getargs.h"
 #include "gram.h"
 #include "muscle_tab.h"
-#include "output.h"
+#include "quotearg.h"
 #include "reader.h"
 #include "symlist.h"
 #include "reader.h"
 #include "symlist.h"
+#include "scan-gram.h"
+#include "scan-code.h"
+#include "strverscmp.h"
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
 static YYLTYPE lloc_default (YYLTYPE const *, int);
 
 #define YY_LOCATION_PRINT(File, Loc) \
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
 static YYLTYPE lloc_default (YYLTYPE const *, int);
 
 #define YY_LOCATION_PRINT(File, Loc) \
-          location_print (File, Loc)
+         location_print (File, Loc)
+
+static void version_check (location const *loc, char const *version);
 
 /* Request detailed syntax error messages, and pass them to GRAM_ERROR.
    FIXME: depends on the undocumented availability of YYLLOC.  */
 #undef  yyerror
 #define yyerror(Msg) \
 
 /* Request detailed syntax error messages, and pass them to GRAM_ERROR.
    FIXME: depends on the undocumented availability of YYLLOC.  */
 #undef  yyerror
 #define yyerror(Msg) \
-        gram_error (&yylloc, Msg)
+       gram_error (&yylloc, Msg)
 static void gram_error (location const *, char const *);
 
 static void gram_error (location const *, char const *);
 
-#define YYPRINT(File, Type, Value) \
-       print_token_value (File, Type, &Value)
-static void print_token_value (FILE *, int, YYSTYPE const *);
+static char const *char_name (char);
 
 static void add_param (char const *, char *, location);
 
 
 static void add_param (char const *, char *, location);
 
-symbol_class current_class = unknown_sym;
-uniqstr current_type = 0;
-symbol *current_lhs;
-location current_lhs_location;
-assoc current_assoc;
-int current_prec = 0;
+static symbol_class current_class = unknown_sym;
+static uniqstr current_type = 0;
+static symbol *current_lhs;
+static location current_lhs_location;
+static int current_prec = 0;
+
+#ifdef UINT_FAST8_MAX
+# define YYTYPE_UINT8 uint_fast8_t
+#endif
+#ifdef INT_FAST8_MAX
+# define YYTYPE_INT8 int_fast8_t
+#endif
+#ifdef UINT_FAST16_MAX
+# define YYTYPE_UINT16 uint_fast16_t
+#endif
+#ifdef INT_FAST16_MAX
+# define YYTYPE_INT16 int_fast16_t
+#endif
 %}
 
 %debug
 %}
 
 %debug
+%verbose
 %defines
 %locations
 %pure-parser
 %defines
 %locations
 %pure-parser
@@ -71,9 +88,8 @@ int current_prec = 0;
 {
   /* Bison's grammar can initial empty locations, hence a default
      location is needed. */
 {
   /* Bison's grammar can initial empty locations, hence a default
      location is needed. */
-  @$.start.file   = @$.end.file   = current_file;
-  @$.start.line   = @$.end.line   = 1;
-  @$.start.column = @$.end.column = 0;
+  boundary_set (&@$.start, current_file, 1, 0);
+  boundary_set (&@$.end, current_file, 1, 0);
 }
 
 /* Only NUMBERS have a value.  */
 }
 
 /* Only NUMBERS have a value.  */
@@ -85,6 +101,7 @@ int current_prec = 0;
   char *chars;
   assoc assoc;
   uniqstr uniqstr;
   char *chars;
   assoc assoc;
   uniqstr uniqstr;
+  unsigned char character;
 };
 
 /* Define the tokens together with their human representation.  */
 };
 
 /* Define the tokens together with their human representation.  */
@@ -96,10 +113,8 @@ int current_prec = 0;
 %token PERCENT_NTERM       "%nterm"
 
 %token PERCENT_TYPE        "%type"
 %token PERCENT_NTERM       "%nterm"
 
 %token PERCENT_TYPE        "%type"
-%token PERCENT_DESTRUCTOR  "%destructor {...}"
-%token PERCENT_PRINTER     "%printer {...}"
-
-%token PERCENT_UNION       "%union {...}"
+%token PERCENT_DESTRUCTOR  "%destructor"
+%token PERCENT_PRINTER     "%printer"
 
 %token PERCENT_LEFT        "%left"
 %token PERCENT_RIGHT       "%right"
 
 %token PERCENT_LEFT        "%left"
 %token PERCENT_RIGHT       "%right"
@@ -124,17 +139,18 @@ int current_prec = 0;
   PERCENT_EXPECT_RR      "%expect-rr"
   PERCENT_FILE_PREFIX     "%file-prefix"
   PERCENT_GLR_PARSER      "%glr-parser"
   PERCENT_EXPECT_RR      "%expect-rr"
   PERCENT_FILE_PREFIX     "%file-prefix"
   PERCENT_GLR_PARSER      "%glr-parser"
-  PERCENT_INITIAL_ACTION  "%initial-action {...}"
-  PERCENT_LEX_PARAM       "%lex-param {...}"
+  PERCENT_INITIAL_ACTION  "%initial-action"
+  PERCENT_LEX_PARAM       "%lex-param"
   PERCENT_LOCATIONS       "%locations"
   PERCENT_NAME_PREFIX     "%name-prefix"
   PERCENT_NO_DEFAULT_PREC "%no-default-prec"
   PERCENT_NO_LINES        "%no-lines"
   PERCENT_NONDETERMINISTIC_PARSER
   PERCENT_LOCATIONS       "%locations"
   PERCENT_NAME_PREFIX     "%name-prefix"
   PERCENT_NO_DEFAULT_PREC "%no-default-prec"
   PERCENT_NO_LINES        "%no-lines"
   PERCENT_NONDETERMINISTIC_PARSER
-                          "%nondeterministic-parser"
+                         "%nondeterministic-parser"
   PERCENT_OUTPUT          "%output"
   PERCENT_OUTPUT          "%output"
-  PERCENT_PARSE_PARAM     "%parse-param {...}"
+  PERCENT_PARSE_PARAM     "%parse-param"
   PERCENT_PURE_PARSER     "%pure-parser"
   PERCENT_PURE_PARSER     "%pure-parser"
+  PERCENT_REQUIRE        "%require"
   PERCENT_SKELETON        "%skeleton"
   PERCENT_START           "%start"
   PERCENT_TOKEN_TABLE     "%token-table"
   PERCENT_SKELETON        "%skeleton"
   PERCENT_START           "%start"
   PERCENT_TOKEN_TABLE     "%token-table"
@@ -142,30 +158,38 @@ int current_prec = 0;
   PERCENT_YACC            "%yacc"
 ;
 
   PERCENT_YACC            "%yacc"
 ;
 
-%token TYPE            "type"
+%token BRACED_CODE     "{...}"
+%token CHAR            "char"
+%token EPILOGUE        "epilogue"
 %token EQUAL           "="
 %token EQUAL           "="
-%token SEMICOLON       ";"
-%token PIPE            "|"
 %token ID              "identifier"
 %token ID_COLON        "identifier:"
 %token PERCENT_PERCENT "%%"
 %token ID              "identifier"
 %token ID_COLON        "identifier:"
 %token PERCENT_PERCENT "%%"
+%token PIPE            "|"
 %token PROLOGUE        "%{...%}"
 %token PROLOGUE        "%{...%}"
-%token EPILOGUE        "epilogue"
-%token BRACED_CODE     "{...}"
+%token SEMICOLON       ";"
+%token TYPE            "type"
+
+%type <character> CHAR
+%printer { fputs (char_name ($$), stderr); } CHAR
+
+%type <chars> STRING string_content "{...}" PROLOGUE EPILOGUE
+%printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
+         STRING string_content
+%printer { fprintf (stderr, "{\n%s\n}", $$); } "{...}" PROLOGUE EPILOGUE
 
 
+%type <uniqstr> TYPE ID ID_COLON
+%printer { fprintf (stderr, "<%s>", $$); } TYPE
+%printer { fputs ($$, stderr); } ID
+%printer { fprintf (stderr, "%s:", $$); } ID_COLON
 
 
-%type <chars> STRING string_content
-             "%destructor {...}"
-             "%initial-action {...}"
-             "%lex-param {...}"
-             "%parse-param {...}"
-             "%printer {...}"
-             "%union {...}"
-             BRACED_CODE action
-             PROLOGUE EPILOGUE
-%type <uniqstr> TYPE
 %type <integer> INT
 %type <integer> INT
-%type <symbol> ID ID_COLON symbol string_as_id
+%printer { fprintf (stderr, "%d", $$); } INT
+
+%type <symbol> id id_colon symbol string_as_id
+%printer { fprintf (stderr, "%s", $$->tag); } id symbol string_as_id
+%printer { fprintf (stderr, "%s:", $$->tag); } id_colon
+
 %type <assoc> precedence_declarator
 %type <list>  symbols.1
 %%
 %type <assoc> precedence_declarator
 %type <list>  symbols.1
 %%
@@ -186,31 +210,38 @@ declarations:
 
 declaration:
   grammar_declaration
 
 declaration:
   grammar_declaration
-| PROLOGUE                                 { prologue_augment ($1, @1); }
+| PROLOGUE                         { prologue_augment (translate_code ($1, @1),
+                                                      @1); }
 | "%debug"                                 { debug_flag = true; }
 | "%debug"                                 { debug_flag = true; }
+| "%define" string_content
+    {
+      static char one[] = "1";
+      muscle_insert ($2, one);
+    }
 | "%define" string_content string_content  { muscle_insert ($2, $3); }
 | "%defines"                               { defines_flag = true; }
 | "%error-verbose"                         { error_verbose = true; }
 | "%expect" INT                            { expected_sr_conflicts = $2; }
 | "%define" string_content string_content  { muscle_insert ($2, $3); }
 | "%defines"                               { defines_flag = true; }
 | "%error-verbose"                         { error_verbose = true; }
 | "%expect" INT                            { expected_sr_conflicts = $2; }
-| "%expect-rr" INT                        { expected_rr_conflicts = $2; }
+| "%expect-rr" INT                        { expected_rr_conflicts = $2; }
 | "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
 | "%glr-parser"
 | "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
 | "%glr-parser"
-  {
-    nondeterministic_parser = true;
-    glr_parser = true;
-  }
-| "%initial-action {...}"
-  {
-    muscle_code_grow ("initial_action", $1, @1);
-  }
-| "%lex-param {...}"                      { add_param ("lex_param", $1, @1); }
+    {
+      nondeterministic_parser = true;
+      glr_parser = true;
+    }
+| "%initial-action" "{...}"
+    {
+      muscle_code_grow ("initial_action", translate_symbol_action ($2, @2), @2);
+    }
+| "%lex-param" "{...}"                    { add_param ("lex_param", $2, @2); }
 | "%locations"                             { locations_flag = true; }
 | "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
 | "%no-lines"                              { no_lines_flag = true; }
 | "%locations"                             { locations_flag = true; }
 | "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
 | "%no-lines"                              { no_lines_flag = true; }
-| "%nondeterministic-parser"              { nondeterministic_parser = true; }
+| "%nondeterministic-parser"              { nondeterministic_parser = true; }
 | "%output" "=" string_content             { spec_outfile = $3; }
 | "%output" "=" string_content             { spec_outfile = $3; }
-| "%parse-param {...}"                    { add_param ("parse_param", $1, @1); }
+| "%parse-param" "{...}"                  { add_param ("parse_param", $2, @2); }
 | "%pure-parser"                           { pure_parser = true; }
 | "%pure-parser"                           { pure_parser = true; }
+| "%require" string_content                { version_check (&@2, $2); }
 | "%skeleton" string_content               { skeleton = $2; }
 | "%token-table"                           { token_table_flag = true; }
 | "%verbose"                               { report_flag = report_states; }
 | "%skeleton" string_content               { skeleton = $2; }
 | "%token-table"                           { token_table_flag = true; }
 | "%verbose"                               { report_flag = report_states; }
@@ -225,25 +256,21 @@ grammar_declaration:
     {
       grammar_start_symbol_set ($2, @2);
     }
     {
       grammar_start_symbol_set ($2, @2);
     }
-| "%union {...}"
-    {
-      typed = true;
-      MUSCLE_INSERT_INT ("stype_line", @1.start.line);
-      muscle_insert ("stype", $1);
-    }
-| "%destructor {...}" symbols.1
+| "%destructor" "{...}" symbols.1
     {
       symbol_list *list;
     {
       symbol_list *list;
-      for (list = $2; list; list = list->next)
-       symbol_destructor_set (list->sym, $1, @1);
-      symbol_list_free ($2);
+      const char *action = translate_symbol_action ($2, @2);
+      for (list = $3; list; list = list->next)
+       symbol_destructor_set (list->sym, action, @2);
+      symbol_list_free ($3);
     }
     }
-| "%printer {...}" symbols.1
+| "%printer" "{...}" symbols.1
     {
       symbol_list *list;
     {
       symbol_list *list;
-      for (list = $2; list; list = list->next)
-       symbol_printer_set (list->sym, $1, list->location);
-      symbol_list_free ($2);
+      const char *action = translate_symbol_action ($2, @2);
+      for (list = $3; list; list = list->next)
+       symbol_printer_set (list->sym, action, @2);
+      symbol_list_free ($3);
     }
 | "%default-prec"
     {
     }
 | "%default-prec"
     {
@@ -255,6 +282,40 @@ grammar_declaration:
     }
 ;
 
     }
 ;
 
+
+/*----------*
+ | %union.  |
+ *----------*/
+
+%token PERCENT_UNION "%union";
+
+union_name:
+  /* Nothing. */ {}
+| ID             { muscle_code_grow ("union_name", $1, @1); }
+;
+
+grammar_declaration:
+  "%union" union_name "{...}"
+    {
+      char const *body = $3;
+
+      if (typed)
+       {
+         /* Concatenate the union bodies, turning the first one's
+            trailing '}' into '\n', and omitting the second one's '{'.  */
+         char *code = muscle_find ("stype");
+         code[strlen (code) - 1] = '\n';
+         body++;
+       }
+
+      typed = true;
+      muscle_code_grow ("stype", body, @3);
+    }
+;
+
+
+
+
 symbol_declaration:
   "%nterm" { current_class = nterm_sym; } symbol_defs.1
     {
 symbol_declaration:
   "%nterm" { current_class = nterm_sym; } symbol_defs.1
     {
@@ -302,7 +363,6 @@ type.opt:
 ;
 
 /* One or more nonterminals to be %typed. */
 ;
 
 /* One or more nonterminals to be %typed. */
-
 symbols.1:
   symbol            { $$ = symbol_list_new ($1, @1); }
 | symbols.1 symbol  { $$ = symbol_list_prepend ($1, $2, @2); }
 symbols.1:
   symbol            { $$ = symbol_list_new ($1, @1); }
 | symbols.1 symbol  { $$ = symbol_list_prepend ($1, $2, @2); }
@@ -314,26 +374,26 @@ symbol_def:
      {
        current_type = $1;
      }
      {
        current_type = $1;
      }
-| ID
+| id
      {
      {
-       symbol_class_set ($1, current_class, @1);
+       symbol_class_set ($1, current_class, @1, true);
        symbol_type_set ($1, current_type, @1);
      }
        symbol_type_set ($1, current_type, @1);
      }
-| ID INT
+| id INT
     {
     {
-      symbol_class_set ($1, current_class, @1);
+      symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
       symbol_user_token_number_set ($1, $2, @2);
     }
       symbol_type_set ($1, current_type, @1);
       symbol_user_token_number_set ($1, $2, @2);
     }
-| ID string_as_id
+| id string_as_id
     {
     {
-      symbol_class_set ($1, current_class, @1);
+      symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
       symbol_make_alias ($1, $2, @$);
     }
       symbol_type_set ($1, current_type, @1);
       symbol_make_alias ($1, $2, @$);
     }
-| ID INT string_as_id
+| id INT string_as_id
     {
     {
-      symbol_class_set ($1, current_class, @1);
+      symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
       symbol_user_token_number_set ($1, $2, @2);
       symbol_make_alias ($1, $3, @$);
       symbol_type_set ($1, current_type, @1);
       symbol_user_token_number_set ($1, $2, @2);
       symbol_make_alias ($1, $3, @$);
@@ -361,10 +421,6 @@ grammar:
 rules_or_grammar_declaration:
   rules
 | grammar_declaration ";"
 rules_or_grammar_declaration:
   rules
 | grammar_declaration ";"
-    {
-      if (yacc_flag)
-       complain_at (@$, _("POSIX forbids declarations in the grammar"));
-    }
 | error ";"
     {
       yyerrok;
 | error ";"
     {
       yyerrok;
@@ -372,22 +428,23 @@ rules_or_grammar_declaration:
 ;
 
 rules:
 ;
 
 rules:
-  ID_COLON { current_lhs = $1; current_lhs_location = @1; } rhses.1
+  id_colon { current_lhs = $1; current_lhs_location = @1; } rhses.1
 ;
 
 rhses.1:
 ;
 
 rhses.1:
-  rhs                { grammar_rule_end (@1); }
-| rhses.1 "|" rhs    { grammar_rule_end (@3); }
+  rhs                { grammar_current_rule_end (@1); }
+| rhses.1 "|" rhs    { grammar_current_rule_end (@3); }
 | rhses.1 ";"
 ;
 
 rhs:
   /* Nothing.  */
 | rhses.1 ";"
 ;
 
 rhs:
   /* Nothing.  */
-    { grammar_rule_begin (current_lhs, current_lhs_location); }
+    { grammar_current_rule_begin (current_lhs, current_lhs_location); }
 | rhs symbol
     { grammar_current_rule_symbol_append ($2, @2); }
 | rhs symbol
     { grammar_current_rule_symbol_append ($2, @2); }
-| rhs action
-    { grammar_current_rule_action_append ($2, @2); }
+| rhs "{...}"
+    { grammar_current_rule_action_append (gram_last_string,
+                                         gram_last_braced_code_loc); }
 | rhs "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
 | rhs "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
@@ -396,40 +453,57 @@ rhs:
     { grammar_current_rule_merge_set ($3, @3); }
 ;
 
     { grammar_current_rule_merge_set ($3, @3); }
 ;
 
-symbol:
-  ID              { $$ = $1; }
-| string_as_id    { $$ = $1; }
+
+/*---------------*
+ | Identifiers.  |
+ *---------------*/
+
+/* Identifiers are returned as uniqstr values by the scanner.
+   Depending on their use, we may need to make them genuine symbols.  */
+
+id:
+  ID
+    { $$ = symbol_get ($1, @1); }
+| CHAR
+    {
+      $$ = symbol_get (char_name ($1), @1);
+      symbol_class_set ($$, token_sym, @1, false);
+      symbol_user_token_number_set ($$, $1, @1);
+    }
 ;
 
 ;
 
-action:
-  BRACED_CODE
-   { $$ = $1; }
+id_colon:
+  ID_COLON { $$ = symbol_get ($1, @1); }
 ;
 
 ;
 
-/* A string used as an ID: we have to keep the quotes. */
+
+symbol:
+  id
+| string_as_id
+;
+
+/* A string used as an ID: quote it.  */
 string_as_id:
   STRING
     {
 string_as_id:
   STRING
     {
-      $$ = symbol_get ($1, @1);
-      symbol_class_set ($$, token_sym, @1);
+      $$ = symbol_get (quotearg_style (c_quoting_style, $1), @1);
+      symbol_class_set ($$, token_sym, @1, false);
     }
 ;
 
     }
 ;
 
-/* A string used for its contents.  Strip the quotes. */
+/* A string used for its contents.  Don't quote it.  */
 string_content:
   STRING
 string_content:
   STRING
-    {
-      $$ = $1 + 1;
-      $$[strlen ($$) - 1] = '\0';
-    };
+    { $$ = $1; }
+;
 
 
 epilogue.opt:
   /* Nothing.  */
 | "%%" EPILOGUE
     {
 
 
 epilogue.opt:
   /* Nothing.  */
 | "%%" EPILOGUE
     {
-      muscle_code_grow ("epilogue", $2, @2);
-      scanner_last_string_free ();
+      muscle_code_grow ("epilogue", translate_code ($2, @2), @2);
+      gram_scanner_last_string_free ();
     }
 ;
 
     }
 ;
 
@@ -480,7 +554,8 @@ add_param (char const *type, char *decl, location loc)
   char const *name_start = NULL;
   char *p;
 
   char const *name_start = NULL;
   char *p;
 
-  for (p = decl; *p; p++)
+  /* Stop on last actual character.  */
+  for (p = decl; p[1]; p++)
     if ((p == decl
         || ! memchr (alphanum, p[-1], sizeof alphanum))
        && memchr (alphanum, p[0], sizeof alphanum - 10))
     if ((p == decl
         || ! memchr (alphanum, p[-1], sizeof alphanum))
        && memchr (alphanum, p[0], sizeof alphanum - 10))
@@ -490,7 +565,7 @@ add_param (char const *type, char *decl, location loc)
      the braces.  */
   while (*--p == ' ' || *p == '\t')
     continue;
      the braces.  */
   while (*--p == ' ' || *p == '\t')
     continue;
-  *p = '\0';
+  p[1] = '\0';
   while (*++decl == ' ' || *decl == '\t')
     continue;
 
   while (*++decl == ' ' || *decl == '\t')
     continue;
 
@@ -513,49 +588,17 @@ add_param (char const *type, char *decl, location loc)
       free (name);
     }
 
       free (name);
     }
 
-  scanner_last_string_free ();
+  gram_scanner_last_string_free ();
 }
 
 }
 
-/*----------------------------------------------------.
-| When debugging the parser, display tokens' values.  |
-`----------------------------------------------------*/
-
 static void
 static void
-print_token_value (FILE *file, int type, YYSTYPE const *value)
+version_check (location const *loc, char const *version)
 {
 {
-  fputc (' ', file);
-  switch (type)
+  if (strverscmp (version, PACKAGE_VERSION) > 0)
     {
     {
-    case ID:
-      fprintf (file, " = %s", value->symbol->tag);
-      break;
-
-    case INT:
-      fprintf (file, " = %d", value->integer);
-      break;
-
-    case STRING:
-      fprintf (file, " = \"%s\"", value->chars);
-      break;
-
-    case TYPE:
-      fprintf (file, " = <%s>", value->uniqstr);
-      break;
-
-    case BRACED_CODE:
-    case PERCENT_DESTRUCTOR:
-    case PERCENT_LEX_PARAM:
-    case PERCENT_PARSE_PARAM:
-    case PERCENT_PRINTER:
-    case PERCENT_UNION:
-    case PROLOGUE:
-    case EPILOGUE:
-      fprintf (file, " = {{ %s }}", value->chars);
-      break;
-
-    default:
-      fprintf (file, "unknown token type");
-      break;
+      complain_at (*loc, "require bison %s, but have %s",
+                  version, PACKAGE_VERSION);
+      exit (63);
     }
 }
 
     }
 }
 
@@ -568,5 +611,18 @@ gram_error (location const *loc, char const *msg)
 char const *
 token_name (int type)
 {
 char const *
 token_name (int type)
 {
-  return yytname[type];
+  return yytname[YYTRANSLATE (type)];
+}
+
+static char const *
+char_name (char c)
+{
+  if (c == '\'')
+    return "'\\''";
+  else
+    {
+      char buf[4];
+      buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
+      return quotearg_style (escape_quoting_style, buf);
+    }
 }
 }