]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
Various DJGGP specific issues in /djgpp.
[bison.git] / src / parse-gram.y
index 6a98d202ab8681b5c5ec9b907bc29a4f7e523a72..11cd489e36f578999f3d6e5c5ddc9b040385d23f 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 "quotearg.h"
 #include "reader.h"
 #include "symlist.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);
 
 /* 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 *);
 
-#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);
 
-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
+%verbose
 %defines
 %locations
 %pure-parser
@@ -132,10 +145,11 @@ int current_prec = 0;
   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_PURE_PARSER     "%pure-parser"
+  PERCENT_REQUIRE        "%require"
   PERCENT_SKELETON        "%skeleton"
   PERCENT_START           "%start"
   PERCENT_TOKEN_TABLE     "%token-table"
@@ -162,11 +176,25 @@ int current_prec = 0;
              "%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 {...}"
+             "%union {...}"
              PROLOGUE EPILOGUE
 %type <uniqstr> TYPE
+%printer { fprintf (stderr, "<%s>", $$); } TYPE
 %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
 %%
@@ -189,29 +217,35 @@ declaration:
   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; }
 | "%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"
-  {
-    nondeterministic_parser = true;
-    glr_parser = true;
-  }
+    {
+      nondeterministic_parser = true;
+      glr_parser = true;
+    }
 | "%initial-action {...}"
-  {
-    muscle_code_grow ("initial_action", $1, @1);
-  }
+    {
+      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; }
-| "%nondeterministic-parser"              { nondeterministic_parser = true; }
+| "%nondeterministic-parser"              { nondeterministic_parser = true; }
 | "%output" "=" string_content             { spec_outfile = $3; }
 | "%parse-param {...}"                    { add_param ("parse_param", $1, @1); }
 | "%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; }
@@ -228,9 +262,19 @@ 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
     {
@@ -243,7 +287,7 @@ grammar_declaration:
     {
       symbol_list *list;
       for (list = $2; list; list = list->next)
-       symbol_printer_set (list->sym, $1, list->location);
+       symbol_printer_set (list->sym, $1, @1);
       symbol_list_free ($2);
     }
 | "%default-prec"
@@ -317,24 +361,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, @$);
@@ -362,10 +406,6 @@ grammar:
 rules_or_grammar_declaration:
   rules
 | grammar_declaration ";"
-    {
-      if (yacc_flag)
-       complain_at (@$, _("POSIX forbids declarations in the grammar"));
-    }
 | error ";"
     {
       yyerrok;
@@ -377,18 +417,17 @@ 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 "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
@@ -402,9 +441,21 @@ symbol:
 | string_as_id    { $$ = $1; }
 ;
 
+/* Handle the semantics of an action specially, with a mid-rule
+   action, so that grammar_current_rule_action_append is invoked
+   immediately after the braced code is read by the scanner.
+
+   This implementation relies on the LALR(1) parsing algorithm.
+   If grammar_current_rule_action_append were executed in a normal
+   action for this rule, then when the input grammar contains two
+   successive actions, the scanner would have to read both actions
+   before reducing this rule.  That wouldn't work, since the scanner
+   relies on all preceding input actions being processed by
+   grammar_current_rule_action_append before it scans the next
+   action.  */
 action:
+    { grammar_current_rule_action_append (last_string, last_braced_code_loc); }
   BRACED_CODE
-    { $$ = $1; }
 ;
 
 /* A string used as an ID: quote it.  */
@@ -412,7 +463,7 @@ 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);
     }
 ;
 
@@ -516,46 +567,14 @@ add_param (char const *type, char *decl, location loc)
   scanner_last_string_free ();
 }
 
-/*----------------------------------------------------.
-| When debugging the parser, display tokens' values.  |
-`----------------------------------------------------*/
-
 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 +587,5 @@ gram_error (location const *loc, char const *msg)
 char const *
 token_name (int type)
 {
-  return yytname[type];
+  return yytname[YYTRANSLATE (type)];
 }