]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
* bootstrap: Undo changes to gnulib files that autoreconf made.
[bison.git] / src / parse-gram.y
index dad4e8cf3041c5f8e41ef6356acd3c2fff87f8df..f45873513b967b455baf71f18432fce9577c1809 100644 (file)
@@ -1,6 +1,6 @@
-/* Bison Grammar Parser                             -*- C -*-
+%{/* Bison Grammar Parser                             -*- C -*-
 
 
-   Copyright (C) 2002, 2003 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
 */
 
 */
 
-
-%debug
-%defines
-%locations
-%pure-parser
-// %error-verbose
-%defines
-%name-prefix="gram_"
-
-%{
+#include <config.h>
 #include "system.h"
 
 #include "complain.h"
 #include "system.h"
 
 #include "complain.h"
 #include "gram.h"
 #include "muscle_tab.h"
 #include "output.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"
-
-/* Produce verbose syntax errors.  */
-#define YYERROR_VERBOSE 1
+#include "strverscmp.h"
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
 static YYLTYPE lloc_default (YYLTYPE const *, int);
 
 
 #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)
+
+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
 /* Request detailed syntax error messages, and pass them to GRAM_ERROR.
    FIXME: depends on the undocumented availability of YYLLOC.  */
 #undef  yyerror
@@ -55,20 +50,32 @@ static YYLTYPE lloc_default (YYLTYPE const *, int);
         gram_error (&yylloc, Msg)
 static void gram_error (location const *, char const *);
 
         gram_error (&yylloc, Msg)
 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 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;
 %}
 
 %}
 
+%debug
+%verbose
+%defines
+%locations
+%pure-parser
+%error-verbose
+%defines
+%name-prefix="gram_"
+
+%initial-action
+{
+  /* 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;
+}
 
 /* Only NUMBERS have a value.  */
 %union
 
 /* Only NUMBERS have a value.  */
 %union
@@ -109,26 +116,32 @@ int current_prec = 0;
 `----------------------*/
 
 %token
 `----------------------*/
 
 %token
-  PERCENT_DEBUG         "%debug"
-  PERCENT_DEFINE        "%define"
-  PERCENT_DEFINES       "%defines"
-  PERCENT_ERROR_VERBOSE "%error-verbose"
-  PERCENT_EXPECT        "%expect"
-  PERCENT_FILE_PREFIX   "%file-prefix"
-  PERCENT_GLR_PARSER    "%glr-parser"
-  PERCENT_LEX_PARAM     "%lex-param {...}"
-  PERCENT_LOCATIONS     "%locations"
-  PERCENT_NAME_PREFIX   "%name-prefix"
-  PERCENT_NO_LINES      "%no-lines"
-  PERCENT_NONDETERMINISTIC_PARSER    "%nondeterministic-parser"
-  PERCENT_OUTPUT        "%output"
-  PERCENT_PARSE_PARAM   "%parse-param {...}"
-  PERCENT_PURE_PARSER   "%pure-parser"
-  PERCENT_SKELETON      "%skeleton"
-  PERCENT_START         "%start"
-  PERCENT_TOKEN_TABLE   "%token-table"
-  PERCENT_VERBOSE       "%verbose"
-  PERCENT_YACC          "%yacc"
+  PERCENT_DEBUG           "%debug"
+  PERCENT_DEFAULT_PREC    "%default-prec"
+  PERCENT_DEFINE          "%define"
+  PERCENT_DEFINES         "%defines"
+  PERCENT_ERROR_VERBOSE   "%error-verbose"
+  PERCENT_EXPECT          "%expect"
+  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_LOCATIONS       "%locations"
+  PERCENT_NAME_PREFIX     "%name-prefix"
+  PERCENT_NO_DEFAULT_PREC "%no-default-prec"
+  PERCENT_NO_LINES        "%no-lines"
+  PERCENT_NONDETERMINISTIC_PARSER
+                          "%nondeterministic-parser"
+  PERCENT_OUTPUT          "%output"
+  PERCENT_PARSE_PARAM     "%parse-param {...}"
+  PERCENT_PURE_PARSER     "%pure-parser"
+  PERCENT_REQUIRE        "%require"
+  PERCENT_SKELETON        "%skeleton"
+  PERCENT_START           "%start"
+  PERCENT_TOKEN_TABLE     "%token-table"
+  PERCENT_VERBOSE         "%verbose"
+  PERCENT_YACC            "%yacc"
 ;
 
 %token TYPE            "type"
 ;
 
 %token TYPE            "type"
@@ -145,6 +158,18 @@ int current_prec = 0;
 
 %type <chars> STRING string_content
              "%destructor {...}"
 
 %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
+%printer { fprintf (stderr, "{\n%s\n}", $$); }
+             "%destructor {...}"
+             "%initial-action {...}"
              "%lex-param {...}"
              "%parse-param {...}"
              "%printer {...}"
              "%lex-param {...}"
              "%parse-param {...}"
              "%printer {...}"
@@ -152,8 +177,13 @@ int current_prec = 0;
              BRACED_CODE action
              PROLOGUE EPILOGUE
 %type <uniqstr> TYPE
              BRACED_CODE action
              PROLOGUE EPILOGUE
 %type <uniqstr> TYPE
+%printer { fprintf (stderr, "<%s>", $$); } TYPE
 %type <integer> INT
 %type <integer> INT
-%type <symbol> ID ID_COLON symbol string_as_id
+%printer { fprintf (stderr, "%d", $$); } INT
+%type <symbol> 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
 %type <list>  symbols.1
 %%
 %type <assoc> precedence_declarator
 %type <list>  symbols.1
 %%
@@ -176,26 +206,40 @@ declaration:
   grammar_declaration
 | PROLOGUE                                 { prologue_augment ($1, @1); }
 | "%debug"                                 { debug_flag = true; }
   grammar_declaration
 | PROLOGUE                                 { prologue_augment ($1, @1); }
 | "%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; }
 | "%define" string_content string_content  { muscle_insert ($2, $3); }
 | "%defines"                               { defines_flag = true; }
 | "%error-verbose"                         { error_verbose = true; }
-| "%expect" INT                            { expected_conflicts = $2; }
+| "%expect" INT                            { expected_sr_conflicts = $2; }
+| "%expect-rr" INT                        { expected_rr_conflicts = $2; }
 | "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
 | "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
-| "%glr-parser"                           { nondeterministic_parser = true;
-                                             glr_parser = true; }
+| "%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); }
 | "%locations"                             { locations_flag = true; }
 | "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
 | "%no-lines"                              { no_lines_flag = true; }
 | "%lex-param {...}"                      { add_param ("lex_param", $1, @1); }
 | "%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", $1, @1); }
 | "%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; }
 | "%yacc"                                  { yacc_flag = true; }
 | "%skeleton" string_content               { skeleton = $2; }
 | "%token-table"                           { token_table_flag = true; }
 | "%verbose"                               { report_flag = report_states; }
 | "%yacc"                                  { yacc_flag = true; }
-| ";"
+| /*FIXME: Err?  What is this horror doing here? */ ";"
 ;
 
 grammar_declaration:
 ;
 
 grammar_declaration:
@@ -207,9 +251,19 @@ grammar_declaration:
     }
 | "%union {...}"
     {
     }
 | "%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;
       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
     {
@@ -225,6 +279,14 @@ grammar_declaration:
        symbol_printer_set (list->sym, $1, list->location);
       symbol_list_free ($2);
     }
        symbol_printer_set (list->sym, $1, list->location);
       symbol_list_free ($2);
     }
+| "%default-prec"
+    {
+      default_prec = true;
+    }
+| "%no-default-prec"
+    {
+      default_prec = false;
+    }
 ;
 
 symbol_declaration:
 ;
 
 symbol_declaration:
@@ -288,24 +350,24 @@ symbol_def:
      }
 | ID
      {
      }
 | 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_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_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_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, @$);
       symbol_type_set ($1, current_type, @1);
       symbol_user_token_number_set ($1, $2, @2);
       symbol_make_alias ($1, $3, @$);
@@ -333,10 +395,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;
@@ -348,14 +406,14 @@ rules:
 ;
 
 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 action
 | rhs symbol
     { grammar_current_rule_symbol_append ($2, @2); }
 | rhs action
@@ -375,32 +433,30 @@ symbol:
 
 action:
   BRACED_CODE
 
 action:
   BRACED_CODE
-   { $$ = $1; }
+    { $$ = $1; }
 ;
 
 ;
 
-/* A string used as an ID: we have to keep the quotes. */
+/* 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
     {
-      epilogue_augment ($2, @2);
+      muscle_code_grow ("epilogue", $2, @2);
       scanner_last_string_free ();
     }
 ;
       scanner_last_string_free ();
     }
 ;
@@ -418,7 +474,11 @@ lloc_default (YYLTYPE const *rhs, int n)
 {
   int i;
   YYLTYPE loc;
 {
   int i;
   YYLTYPE loc;
-  loc.start = loc.end = rhs[n].end;
+
+  /* SGI MIPSpro 7.4.1m miscompiles "loc.start = loc.end = rhs[n].end;".
+     The bug is fixed in 7.4.2m, but play it safe for now.  */
+  loc.start = rhs[n].end;
+  loc.end = rhs[n].end;
 
   /* Ignore empty nonterminals the start of the the right-hand side.
      Do not bother to ignore them at the end of the right-hand side,
 
   /* Ignore empty nonterminals the start of the the right-hand side.
      Do not bother to ignore them at the end of the right-hand side,
@@ -440,22 +500,28 @@ lloc_default (YYLTYPE const *rhs, int n)
 static void
 add_param (char const *type, char *decl, location loc)
 {
 static void
 add_param (char const *type, char *decl, location loc)
 {
-  static char const alphanum[] =
-    "0123456789"
+  static char const alphanum[26 + 26 + 1 + 10] =
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "_";
-  char const *alpha = alphanum + 10;
+    "_"
+    "0123456789";
   char const *name_start = NULL;
   char *p;
 
   char const *name_start = NULL;
   char *p;
 
-  for (p = decl; *p; p++)
-    if ((p == decl || ! strchr (alphanum, p[-1])) && strchr (alpha, p[0]))
+  /* 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))
       name_start = p;
 
       name_start = p;
 
-  /* Strip the surrounding '{' and '}'.  */
-  decl++;
-  p[-1] = '\0';
+  /* Strip the surrounding '{' and '}', and any blanks just inside
+     the braces.  */
+  while (*--p == ' ' || *p == '\t')
+    continue;
+  p[1] = '\0';
+  while (*++decl == ' ' || *decl == '\t')
+    continue;
 
   if (! name_start)
     complain_at (loc, _("missing identifier in parameter declaration"));
 
   if (! name_start)
     complain_at (loc, _("missing identifier in parameter declaration"));
@@ -465,7 +531,7 @@ add_param (char const *type, char *decl, location loc)
       size_t name_len;
 
       for (name_len = 1;
       size_t name_len;
 
       for (name_len = 1;
-          name_start[name_len] && strchr (alphanum, name_start[name_len]);
+          memchr (alphanum, name_start[name_len], sizeof alphanum);
           name_len++)
        continue;
 
           name_len++)
        continue;
 
@@ -479,46 +545,14 @@ add_param (char const *type, char *decl, location loc)
   scanner_last_string_free ();
 }
 
   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);
     }
 }
 
     }
 }
 
@@ -531,5 +565,5 @@ 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)];
 }
 }