]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
For associating token numbers with token names for "yacc.c", don't use
[bison.git] / src / parse-gram.y
index 027a773d221d2b914831281cfe9c9cbd8c32b7be..a0c708b3e416edfebb9c85a6e5009d37a3e1c7bf 100644 (file)
@@ -1,6 +1,6 @@
 %{/* Bison Grammar Parser                             -*- C -*-
 
-   Copyright (C) 2002, 2003, 2004, 2005 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.
 
@@ -20,6 +20,7 @@
    02110-1301  USA
 */
 
+#include <config.h>
 #include "system.h"
 
 #include "complain.h"
 #include "getargs.h"
 #include "gram.h"
 #include "muscle_tab.h"
-#include "output.h"
 #include "quotearg.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) \
-          location_print (File, Loc)
+         location_print (File, Loc)
 
 static void version_check (location const *loc, char const *version);
 
@@ -46,17 +48,29 @@ static void version_check (location const *loc, char const *version);
    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 add_param (char const *, char *, location);
 
 static symbol_class current_class = unknown_sym;
 static uniqstr current_type = 0;
-symbol *current_lhs;
-location current_lhs_location;
-assoc current_assoc;
+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
@@ -72,9 +86,8 @@ static int current_prec = 0;
 {
   /* 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.  */
@@ -97,8 +110,8 @@ static int current_prec = 0;
 %token PERCENT_NTERM       "%nterm"
 
 %token PERCENT_TYPE        "%type"
-%token PERCENT_DESTRUCTOR  "%destructor {...}"
-%token PERCENT_PRINTER     "%printer {...}"
+%token PERCENT_DESTRUCTOR  "%destructor"
+%token PERCENT_PRINTER     "%printer"
 
 %token PERCENT_UNION       "%union {...}"
 
@@ -125,18 +138,18 @@ static int current_prec = 0;
   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
-                          "%nondeterministic-parser"
+                         "%nondeterministic-parser"
   PERCENT_OUTPUT          "%output"
-  PERCENT_PARSE_PARAM     "%parse-param {...}"
+  PERCENT_PARSE_PARAM     "%parse-param"
   PERCENT_PURE_PARSER     "%pure-parser"
-  PERCENT_REQUIRE        "%require"
+  PERCENT_REQUIRE        "%require"
   PERCENT_SKELETON        "%skeleton"
   PERCENT_START           "%start"
   PERCENT_TOKEN_TABLE     "%token-table"
@@ -155,33 +168,22 @@ static int current_prec = 0;
 %token EPILOGUE        "epilogue"
 %token BRACED_CODE     "{...}"
 
-
 %type <chars> STRING string_content
-             "%destructor {...}"
-             "%initial-action {...}"
-             "%lex-param {...}"
-             "%parse-param {...}"
-             "%printer {...}"
+             "{...}"
              "%union {...}"
-             BRACED_CODE action
              PROLOGUE EPILOGUE
 %printer { fprintf (stderr, "\"%s\"", $$); }
-              STRING string_content
+             STRING string_content
 %printer { fprintf (stderr, "{\n%s\n}", $$); }
-             "%destructor {...}"
-             "%initial-action {...}"
-             "%lex-param {...}"
-             "%parse-param {...}"
-             "%printer {...}"
+             "{...}"
              "%union {...}"
-             BRACED_CODE action
              PROLOGUE EPILOGUE
 %type <uniqstr> TYPE
 %printer { fprintf (stderr, "<%s>", $$); } TYPE
 %type <integer> INT
 %printer { fprintf (stderr, "%d", $$); } INT
 %type <symbol> ID symbol string_as_id
-%printer { fputs ($$->tag, stderr); } ID symbol string_as_id
+%printer { fprintf (stderr, "%s", $$->tag); } ID symbol string_as_id
 %type <symbol> ID_COLON
 %printer { fprintf (stderr, "%s:", $$->tag); } ID_COLON
 %type <assoc> precedence_declarator
@@ -204,9 +206,14 @@ declarations:
 
 declaration:
   grammar_declaration
-| PROLOGUE                                 { prologue_augment ($1, @1); }
+| PROLOGUE                         { prologue_augment (translate_code ($1, @1),
+                                                      @1); }
 | "%debug"                                 { debug_flag = true; }
-| "%define" string_content                 { muscle_insert ($2, "1"); }
+| "%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; }
@@ -214,21 +221,21 @@ declaration:
 | "%expect-rr" INT                        { expected_rr_conflicts = $2; }
 | "%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; }
 | "%nondeterministic-parser"              { nondeterministic_parser = true; }
 | "%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; }
 | "%require" string_content                { version_check (&@2, $2); }
 | "%skeleton" string_content               { skeleton = $2; }
@@ -247,23 +254,35 @@ grammar_declaration:
     }
 | "%union {...}"
     {
+      char const *body = $1;
+
+      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_INSERT_INT ("stype_line", @1.start.line);
-      muscle_insert ("stype", $1);
+      muscle_code_grow ("stype", body, @1);
     }
-| "%destructor {...}" symbols.1
+| "%destructor" "{...}" symbols.1
     {
       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;
-      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"
     {
@@ -322,7 +341,6 @@ type.opt:
 ;
 
 /* One or more nonterminals to be %typed. */
-
 symbols.1:
   symbol            { $$ = symbol_list_new ($1, @1); }
 | symbols.1 symbol  { $$ = symbol_list_prepend ($1, $2, @2); }
@@ -336,24 +354,24 @@ symbol_def:
      }
 | ID
      {
-       symbol_class_set ($1, current_class, @1);
+       symbol_class_set ($1, current_class, @1, true);
        symbol_type_set ($1, current_type, @1);
      }
 | 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);
     }
 | 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, @$);
     }
 | 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, @$);
@@ -381,10 +399,6 @@ grammar:
 rules_or_grammar_declaration:
   rules
 | grammar_declaration ";"
-    {
-      if (yacc_flag)
-       complain_at (@$, _("POSIX forbids declarations in the grammar"));
-    }
 | error ";"
     {
       yyerrok;
@@ -396,18 +410,19 @@ rules:
 ;
 
 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.  */
-    { 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 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
@@ -421,17 +436,12 @@ symbol:
 | string_as_id    { $$ = $1; }
 ;
 
-action:
-  BRACED_CODE
-    { $$ = $1; }
-;
-
 /* A string used as an ID: quote it.  */
 string_as_id:
   STRING
     {
       $$ = symbol_get (quotearg_style (c_quoting_style, $1), @1);
-      symbol_class_set ($$, token_sym, @1);
+      symbol_class_set ($$, token_sym, @1, false);
     }
 ;
 
@@ -446,8 +456,8 @@ 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 ();
     }
 ;
 
@@ -532,15 +542,18 @@ add_param (char const *type, char *decl, location loc)
       free (name);
     }
 
-  scanner_last_string_free ();
+  gram_scanner_last_string_free ();
 }
 
 static void
 version_check (location const *loc, char const *version)
 {
   if (strverscmp (version, PACKAGE_VERSION) > 0)
-    complain_at (*loc, "require bison %s, but have %s",
-                version, PACKAGE_VERSION);
+    {
+      complain_at (*loc, "require bison %s, but have %s",
+                  version, PACKAGE_VERSION);
+      exit (63);
+    }
 }
 
 static void