]> git.saurik.com Git - bison.git/blobdiff - src/gram.c
Do not let the scan-skel token buffer grow unboundedly in the usual case.
[bison.git] / src / gram.c
index 4d88b39b2c63cea367a8b009fedd6716b4a8488d..cf5a946db983e698269f6f2fa1aaa1800ecbc3ad 100644 (file)
@@ -1,4 +1,5 @@
-/* Allocate input grammar variables for bison,
+/* Allocate input grammar variables for Bison.
+
    Copyright (C) 1984, 1986, 1989, 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
    Copyright (C) 1984, 1986, 1989, 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
 #include "system.h"
 
 
 #include "system.h"
-#include "quotearg.h"
-#include "symtab.h"
+
+#include <quotearg.h>
+
 #include "gram.h"
 #include "gram.h"
-#include "reduce.h"
 #include "reader.h"
 #include "reader.h"
+#include "reduce.h"
+#include "symtab.h"
 
 /* Comments for these variables are in gram.h.  */
 
 
 /* Comments for these variables are in gram.h.  */
 
-item_number_t *ritem = NULL;
+item_number *ritem = NULL;
 unsigned int nritems = 0;
 
 unsigned int nritems = 0;
 
-rule_t *rules = NULL;
-int nrules = 0;
+rule *rules = NULL;
+rule_number nrules = 0;
 
 
-symbol_t **symbols = NULL;
+symbol **symbols = NULL;
 int nsyms = 0;
 int ntokens = 1;
 int nvars = 0;
 
 int nsyms = 0;
 int ntokens = 1;
 int nvars = 0;
 
-symbol_number_t *token_translations = NULL;
+symbol_number *token_translations = NULL;
 
 int max_user_token_number = 256;
 
 
 int max_user_token_number = 256;
 
@@ -47,33 +50,91 @@ int glr_parser = 0;
 int pure_parser = 0;
 
 
 int pure_parser = 0;
 
 
+/*--------------------------------------------------------------.
+| Return true IFF the rule has a `number' smaller than NRULES.  |
+`--------------------------------------------------------------*/
+
+bool
+rule_useful_p (rule *r)
+{
+  return r->number < nrules;
+}
+
+
+/*-------------------------------------------------------------.
+| Return true IFF the rule has a `number' higher than NRULES.  |
+`-------------------------------------------------------------*/
+
+bool
+rule_useless_p (rule *r)
+{
+  return r->number >= nrules;
+}
+
+
+/*--------------------------------------------------------------------.
+| Return true IFF the rule is not flagged as useful *and* is useful.  |
+| In other words, it was discarded because of conflicts.              |
+`--------------------------------------------------------------------*/
+
+bool
+rule_never_reduced_p (rule *r)
+{
+  return !r->useful && r->number < nrules;
+}
+
+
+/*----------------------------------------------------------------.
+| Print this RULE's number and lhs on OUT.  If a PREVIOUS_LHS was |
+| already displayed (by a previous call for another rule), avoid  |
+| useless repetitions.                                            |
+`----------------------------------------------------------------*/
+
+void
+rule_lhs_print (rule *r, symbol *previous_lhs, FILE *out)
+{
+  fprintf (out, "  %3d ", r->number);
+  if (previous_lhs != r->lhs)
+    {
+      fprintf (out, "%s:", r->lhs->tag);
+    }
+  else
+    {
+      int n;
+      for (n = strlen (previous_lhs->tag); n > 0; --n)
+       fputc (' ', out);
+      fputc ('|', out);
+    }
+}
+
+
 /*--------------------------------------.
 | Return the number of symbols in RHS.  |
 `--------------------------------------*/
 
 int
 /*--------------------------------------.
 | Return the number of symbols in RHS.  |
 `--------------------------------------*/
 
 int
-rule_rhs_length (rule_t *rule)
+rule_rhs_length (rule *r)
 {
   int res = 0;
 {
   int res = 0;
-  item_number_t *rhsp;
-  for (rhsp = rule->rhs; *rhsp >= 0; ++rhsp)
+  item_number *rhsp;
+  for (rhsp = r->rhs; *rhsp >= 0; ++rhsp)
     ++res;
   return res;
 }
 
 
 /*-------------------------------.
     ++res;
   return res;
 }
 
 
 /*-------------------------------.
-| Print this RULE's RHS on OUT.  |
+| Print this rule's RHS on OUT.  |
 `-------------------------------*/
 
 void
 `-------------------------------*/
 
 void
-rule_rhs_print (rule_t *rule, FILE *out)
+rule_rhs_print (rule *r, FILE *out)
 {
 {
-  if (*rule->rhs >= 0)
+  if (*r->rhs >= 0)
     {
     {
-      item_number_t *r;
-      for (r = rule->rhs; *r >= 0; r++)
-       fprintf (out, " %s", symbol_tag_get (symbols[*r]));
+      item_number *rp;
+      for (rp = r->rhs; *rp >= 0; rp++)
+       fprintf (out, " %s", symbols[*rp]->tag);
       fputc ('\n', out);
     }
   else
       fputc ('\n', out);
     }
   else
@@ -84,14 +145,14 @@ rule_rhs_print (rule_t *rule, FILE *out)
 
 
 /*-------------------------.
 
 
 /*-------------------------.
-| Print this RULE on OUT.  |
+| Print this rule on OUT.  |
 `-------------------------*/
 
 void
 `-------------------------*/
 
 void
-rule_print (rule_t *rule, FILE *out)
+rule_print (rule *r, FILE *out)
 {
 {
-  fprintf (out, "%s:", symbol_tag_get (rule->lhs));
-  rule_rhs_print (rule, out);
+  fprintf (out, "%s:", r->lhs->tag);
+  rule_rhs_print (r, out);
 }
 
 
 }
 
 
@@ -106,9 +167,9 @@ ritem_print (FILE *out)
   fputs ("RITEM\n", out);
   for (i = 0; i < nritems; ++i)
     if (ritem[i] >= 0)
   fputs ("RITEM\n", out);
   for (i = 0; i < nritems; ++i)
     if (ritem[i] >= 0)
-      fprintf (out, "  %s", symbol_tag_get (symbols[ritem[i]]));
+      fprintf (out, "  %s", symbols[ritem[i]]->tag);
     else
     else
-      fprintf (out, "  (rule %d)\n", -ritem[i] - 1);
+      fprintf (out, "  (rule %d)\n", item_number_as_rule_number (ritem[i]));
   fputs ("\n\n", out);
 }
 
   fputs ("\n\n", out);
 }
 
@@ -121,11 +182,11 @@ size_t
 ritem_longest_rhs (void)
 {
   int max = 0;
 ritem_longest_rhs (void)
 {
   int max = 0;
-  int i;
+  rule_number r;
 
 
-  for (i = 1; i < nrules + 1; ++i)
+  for (r = 0; r < nrules; ++r)
     {
     {
-      int length = rule_rhs_length (&rules[i]);
+      int length = rule_rhs_length (&rules[r]);
       if (length > max)
        max = length;
     }
       if (length > max)
        max = length;
     }
@@ -134,46 +195,34 @@ ritem_longest_rhs (void)
 }
 
 
 }
 
 
-/*----------------------------------------------------------------.
-| Print the grammar's rules numbers from BEGIN (inclusive) to END |
-| (exclusive) on OUT under TITLE.                                 |
-`----------------------------------------------------------------*/
-
-static inline void
-blanks_print (unsigned n, FILE *out)
-{
-  for (/* Nothing*/; n > 0; --n)
-    fputc (' ', out);
-}
+/*-----------------------------------------------------------------.
+| Print the grammar's rules that match FILTER on OUT under TITLE.  |
+`-----------------------------------------------------------------*/
 
 void
 grammar_rules_partial_print (FILE *out, const char *title,
 
 void
 grammar_rules_partial_print (FILE *out, const char *title,
-                            int begin, int end)
+                            rule_filter filter)
 {
   int r;
 {
   int r;
-  symbol_t *last_lhs = NULL;
+  bool first = true;
+  symbol *previous_lhs = NULL;
 
   /* rule # : LHS -> RHS */
 
   /* rule # : LHS -> RHS */
-  fprintf (out, "%s\n\n", title);
-  for (r = begin; r < end; r++)
+  for (r = 0; r < nrules + nuseless_productions; r++)
     {
     {
-      if (last_lhs && last_lhs != rules[r].lhs)
+      if (filter && !filter (&rules[r]))
+       continue;
+      if (first)
+       fprintf (out, "%s\n\n", title);
+      else if (previous_lhs && previous_lhs != rules[r].lhs)
        fputc ('\n', out);
        fputc ('\n', out);
-
-      fprintf (out, "  %3d ", r - 1);
-      if (last_lhs != rules[r].lhs)
-       {
-         last_lhs = rules[r].lhs;
-         fprintf (out, "%s:", symbol_tag_get (last_lhs));
-       }
-      else
-       {
-         blanks_print (strlen (symbol_tag_get (last_lhs)), out);
-         fputc ('|', out);
-       }
+      first = false;
+      rule_lhs_print (&rules[r], previous_lhs, out);
       rule_rhs_print (&rules[r], out);
       rule_rhs_print (&rules[r], out);
+      previous_lhs = rules[r].lhs;
     }
     }
-  fputs ("\n\n", out);
+  if (!first)
+    fputs ("\n\n", out);
 }
 
 
 }
 
 
@@ -184,7 +233,7 @@ grammar_rules_partial_print (FILE *out, const char *title,
 void
 grammar_rules_print (FILE *out)
 {
 void
 grammar_rules_print (FILE *out)
 {
-  grammar_rules_partial_print (out, _("Grammar"), 1, nrules + 1);
+  grammar_rules_partial_print (out, _("Grammar"), rule_useful_p);
 }
 
 
 }
 
 
@@ -195,58 +244,93 @@ grammar_rules_print (FILE *out)
 void
 grammar_dump (FILE *out, const char *title)
 {
 void
 grammar_dump (FILE *out, const char *title)
 {
-  int i;
-  item_number_t *r;
-
   fprintf (out, "%s\n\n", title);
   fprintf (out,
           "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
           ntokens, nvars, nsyms, nrules, nritems);
   fprintf (out, "%s\n\n", title);
   fprintf (out,
           "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
           ntokens, nvars, nsyms, nrules, nritems);
+
+
   fprintf (out, "Variables\n---------\n\n");
   fprintf (out, "Variables\n---------\n\n");
-  fprintf (out, "Value  Sprec  Sassoc  Tag\n");
-  for (i = ntokens; i < nsyms; i++)
-    fprintf (out, "%5d  %5d   %5d  %s\n",
-            i,
-            symbols[i]->prec, symbols[i]->assoc,
-            symbol_tag_get (symbols[i]));
-  fprintf (out, "\n\n");
+  {
+    symbol_number i;
+    fprintf (out, "Value  Sprec  Sassoc  Tag\n");
+
+    for (i = ntokens; i < nsyms; i++)
+      fprintf (out, "%5d  %5d   %5d  %s\n",
+              i,
+              symbols[i]->prec, symbols[i]->assoc,
+              symbols[i]->tag);
+    fprintf (out, "\n\n");
+  }
+
   fprintf (out, "Rules\n-----\n\n");
   fprintf (out, "Rules\n-----\n\n");
-  fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
-  for (i = 1; i < nrules + nuseless_productions + 1; i++)
-    {
-      int rhs_count = 0;
-      /* Find the last RHS index in ritems. */
-      for (r = rules[i].rhs; *r >= 0; ++r)
-       ++rhs_count;
-      fprintf (out, "%3d (%2d, %2d, %2d, %2d-%2d)   %2d ->",
-              i - 1,
-              rules[i].prec ? rules[i].prec->prec : 0,
-              rules[i].prec ? rules[i].prec->assoc : 0,
-              rules[i].useful,
-              rules[i].rhs - ritem,
-              rules[i].rhs - ritem + rhs_count - 1,
-              rules[i].lhs->number);
-      /* Dumped the RHS. */
-      for (r = rules[i].rhs; *r >= 0; r++)
-       fprintf (out, " %3d", *r);
-      fprintf (out, "  [%d]\n", -(*r) - 1);
-    }
+  {
+    rule_number i;
+    fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
+    for (i = 0; i < nrules + nuseless_productions; i++)
+      {
+       rule *rule_i = &rules[i];
+       item_number *r = NULL;
+       unsigned int rhs_itemno = rule_i->rhs - ritem;
+       unsigned int rhs_count = 0;
+       /* Find the last RHS index in ritems. */
+       for (r = rule_i->rhs; *r >= 0; ++r)
+         ++rhs_count;
+       fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u)   %2d ->",
+                i,
+                rule_i->prec ? rule_i->prec->prec : 0,
+                rule_i->prec ? rule_i->prec->assoc : 0,
+                rule_i->useful,
+                rhs_itemno,
+                rhs_itemno + rhs_count - 1,
+                rule_i->lhs->number);
+       /* Dumped the RHS. */
+       for (r = rule_i->rhs; *r >= 0; r++)
+         fprintf (out, " %3d", *r);
+       fprintf (out, "  [%d]\n", item_number_as_rule_number (*r));
+      }
+  }
   fprintf (out, "\n\n");
   fprintf (out, "\n\n");
+
   fprintf (out, "Rules interpreted\n-----------------\n\n");
   fprintf (out, "Rules interpreted\n-----------------\n\n");
-  for (i = 1; i < nrules + nuseless_productions + 1; i++)
-    {
-      fprintf (out, "%-5d  ", i);
-      rule_print (&rules[i], out);
-    }
+  {
+    rule_number r;
+    for (r = 0; r < nrules + nuseless_productions; r++)
+      {
+       fprintf (out, "%-5d  ", r);
+       rule_print (&rules[r], out);
+      }
+  }
   fprintf (out, "\n\n");
 }
 
 
   fprintf (out, "\n\n");
 }
 
 
+/*------------------------------------------------------------------.
+| Report on STDERR the rules that are not flagged USEFUL, using the |
+| MESSAGE (which can be `useless rule' when invoked after grammar   |
+| reduction, or `never reduced' after conflicts were taken into     |
+| account).                                                         |
+`------------------------------------------------------------------*/
+
+void
+grammar_rules_never_reduced_report (const char *message)
+{
+  rule_number r;
+  for (r = 0; r < nrules ; ++r)
+    if (!rules[r].useful)
+      {
+       location_print (stderr, rules[r].location);
+       fprintf (stderr, ": %s: %s: ",
+                _("warning"), message);
+       rule_print (&rules[r], stderr);
+      }
+}
+
 void
 grammar_free (void)
 {
   XFREE (ritem);
 void
 grammar_free (void)
 {
   XFREE (ritem);
-  free (rules + 1);
+  free (rules);
   XFREE (token_translations);
   /* Free the symbol table data structure.  */
   symbols_free ();
   XFREE (token_translations);
   /* Free the symbol table data structure.  */
   symbols_free ();