]> git.saurik.com Git - bison.git/blobdiff - src/closure.c
(AUTOMAKE_OPTIONS): Remove.
[bison.git] / src / closure.c
index 6d3d22078faabdced2af1a5081d2b6e6c819e9d5..06c50364b3399b530684a163910604354ea44c4d 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines for bison
 /* Subroutines for bison
-   Copyright 1984, 1989, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
    02111-1307, USA.  */
 
 #include "system.h"
    02111-1307, USA.  */
 
 #include "system.h"
-#include "xalloc.h"
+#include "bitset.h"
+#include "bitsetv.h"
+#include "getargs.h"
+#include "symtab.h"
 #include "gram.h"
 #include "gram.h"
+#include "reader.h"
 #include "closure.h"
 #include "derives.h"
 #include "closure.h"
 #include "derives.h"
-#include "warshall.h"
 
 
+/* NITEMSET is the size of the array ITEMSET.  */
 short *itemset;
 short *itemset;
-short *itemsetend;
-static unsigned *ruleset;
+int nitemset;
 
 
-/* internal data.  See comments before set_fderives and set_firsts.  */
-static unsigned *fderives;
-static unsigned *firsts;
+static bitset ruleset;
 
 
-/* number of words required to hold a bit for each rule */
-static int rulesetsize;
+/* internal data.  See comments before set_fderives and set_firsts.  */
+static bitsetv fderives = NULL;
+static bitsetv firsts = NULL;
 
 
-/* number of words required to hold a bit for each variable */
-static int varsetsize;
+/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var.  */
+#define FDERIVES(Var)   fderives[(Var) - ntokens]
+#define   FIRSTS(Var)   firsts[(Var) - ntokens]
 \f
 \f
-#if DEBUG
 
 /*-----------------.
 | Debugging code.  |
 `-----------------*/
 
 static void
 
 /*-----------------.
 | Debugging code.  |
 `-----------------*/
 
 static void
-print_closure (int n)
+print_closure (const char *title, short *array, size_t size)
 {
 {
-  short *isp;
-
-  printf ("\n\nn = %d\n\n", n);
-  for (isp = itemset; isp < itemsetend; isp++)
-    printf ("   %d\n", *isp);
+  size_t i;
+  fprintf (stderr, "Closure: %s\n", title);
+  for (i = 0; i < size; ++i)
+    {
+      short *rp;
+      fprintf (stderr, "  %2d: .", array[i]);
+      for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
+       fprintf (stderr, " %s", symbols[*rp]->tag);
+      fprintf (stderr, "  (rule %d)\n", -*rp - 1);
+    }
+  fputs ("\n\n", stderr);
 }
 
 
 static void
 print_firsts (void)
 {
 }
 
 
 static void
 print_firsts (void)
 {
-  int i;
-  int j;
-  unsigned *rowp;
-
-  printf ("\n\n\nFIRSTS\n\n");
+  int i, j;
 
 
+  fprintf (stderr, "FIRSTS\n");
   for (i = ntokens; i < nsyms; i++)
     {
   for (i = ntokens; i < nsyms; i++)
     {
-      printf ("\n\n%s firsts\n\n", tags[i]);
-
-      rowp = firsts + ((i - ntokens) * varsetsize);
-
+      fprintf (stderr, "\t%s firsts\n", symbols[i]->tag);
       for (j = 0; j < nvars; j++)
       for (j = 0; j < nvars; j++)
-       if (BITISSET (rowp, j))
-         printf ("   %s\n", tags[j + ntokens]);
+       if (bitset_test (FIRSTS (i), j))
+         fprintf (stderr, "\t\t%d (%s)\n",
+                  j + ntokens, symbols[j + ntokens]->tag);
     }
     }
+  fprintf (stderr, "\n\n");
 }
 
 
 static void
 print_fderives (void)
 {
 }
 
 
 static void
 print_fderives (void)
 {
-  int i;
-  int j;
-  unsigned *rp;
-
-  printf ("\n\n\nFDERIVES\n");
+  int i, j;
 
 
+  fprintf (stderr, "FDERIVES\n");
   for (i = ntokens; i < nsyms; i++)
     {
   for (i = ntokens; i < nsyms; i++)
     {
-      printf ("\n\n%s derives\n\n", tags[i]);
-      rp = fderives + i * rulesetsize;
-
+      fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
       for (j = 0; j <= nrules; j++)
       for (j = 0; j <= nrules; j++)
-       if (BITISSET (rp, j))
-         printf ("   %d\n", j);
+       if (bitset_test (FDERIVES (i), j))
+         {
+           short *rhsp;
+           fprintf (stderr, "\t\t%d:", j - 1);
+           for (rhsp = &ritem[rules[j].rhs]; *rhsp >= 0; ++rhsp)
+             fprintf (stderr, " %s", symbols[*rhsp]->tag);
+           fputc ('\n', stderr);
+         }
     }
     }
+  fprintf (stderr, "\n\n");
+}
+
+/*--------------------------------------------------------.
+| Display the MATRIX array of SIZE bitsets of size SIZE.  |
+`--------------------------------------------------------*/
 
 
-  fflush (stdout);
+static void
+bitmatrix_print (const char *title, bitsetv matrix)
+{
+  size_t i, j;
+  size_t size = bitset_size (matrix[0]);
+
+  /* Title. */
+  fprintf (stderr, "%s BEGIN\n", title);
+
+  /* Column numbers. */
+  fputs ("   ", stderr);
+  for (i = 0; i < size; ++i)
+    putc (i / 10 ? '0' + i / 10 : ' ', stderr);
+  putc ('\n', stderr);
+  fputs ("   ", stderr);
+  for (i = 0; i < size; ++i)
+    fprintf (stderr, "%d", i % 10);
+  putc ('\n', stderr);
+
+  /* Bar. */
+  fputs ("  .", stderr);
+  for (i = 0; i < size; ++i)
+    putc ('-', stderr);
+  fputs (".\n", stderr);
+
+  /* Contents. */
+  for (i = 0; i < size; ++i)
+    {
+      fprintf (stderr, "%2d|", i);
+      for (j = 0; j < size; ++j)
+       fputs (bitset_test (matrix[i], j) ? "1" : " ", stderr);
+      fputs ("|\n", stderr);
+    }
+
+  /* Bar. */
+  fputs ("  `", stderr);
+  for (i = 0; i < size; ++i)
+    putc ('-', stderr);
+  fputs ("'\n", stderr);
+
+  /* End title. */
+  fprintf (stderr, "%s END\n\n", title);
 }
 }
-#endif
 \f
 \f
-/*-------------------------------------------------------------------.
-| Set FIRSTS to be an NVARS by NVARS bit matrix indicating which     |
-| items can represent the beginning of the input corresponding to    |
-| which other items.                                                 |
-|                                                                    |
-| For example, if some rule expands symbol 5 into the sequence of    |
-| symbols 8 3 20, the symbol 8 can be the beginning of the data for  |
-| symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is set.  |
-`-------------------------------------------------------------------*/
+/*------------------------------------------------------------------.
+| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
+| items can represent the beginning of the input corresponding to   |
+| which other items.                                                |
+|                                                                   |
+| For example, if some rule expands symbol 5 into the sequence of   |
+| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
+| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
+| (5)) is set.                                                      |
+`------------------------------------------------------------------*/
 
 static void
 set_firsts (void)
 {
 
 static void
 set_firsts (void)
 {
-  unsigned *row;
-  int symbol;
-  short *sp;
-  int rowsize;
-
-  int i;
+  int i, j;
 
 
-  varsetsize = rowsize = WORDSIZE (nvars);
+  firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
 
 
-  firsts = XCALLOC (unsigned, nvars * rowsize);
-
-  row = firsts;
   for (i = ntokens; i < nsyms; i++)
   for (i = ntokens; i < nsyms; i++)
-    {
-      sp = derives[i];
-      while (*sp >= 0)
-       {
-         symbol = ritem[rrhs[*sp++]];
-         if (ISVAR (symbol))
-           {
-             symbol -= ntokens;
-             SETBIT (row, symbol);
-           }
-       }
-
-      row += rowsize;
-    }
-
-  RTC (firsts, nvars);
-
-#ifdef DEBUG
-  print_firsts ();
-#endif
+    for (j = 0; derives[i][j] >= 0; ++j)
+      {
+       int symbol = ritem[rules[derives[i][j]].rhs];
+       if (ISVAR (symbol))
+         bitset_set (FIRSTS (i), symbol - ntokens);
+      }
+
+  if (trace_flag)
+    bitmatrix_print ("RTC: Input", firsts);
+  bitsetv_reflexive_transitive_closure (firsts);
+  if (trace_flag)
+    bitmatrix_print ("RTC: Output", firsts);
+
+  if (trace_flag)
+    print_firsts ();
 }
 
 /*-------------------------------------------------------------------.
 }
 
 /*-------------------------------------------------------------------.
@@ -162,54 +201,22 @@ set_firsts (void)
 static void
 set_fderives (void)
 {
 static void
 set_fderives (void)
 {
-  unsigned *rrow;
-  unsigned *vrow;
-  int j;
-  unsigned cword;
-  short *rp;
-  int b;
-
-  int ruleno;
-  int i;
+  int i, j, k;
 
 
-  fderives = XCALLOC (unsigned, nvars * rulesetsize) - ntokens * rulesetsize;
+  fderives = bitsetv_create (nvars, nrules + 1, BITSET_FIXED);
 
   set_firsts ();
 
 
   set_firsts ();
 
-  rrow = fderives + ntokens * rulesetsize;
-
-  for (i = ntokens; i < nsyms; i++)
-    {
-      vrow = firsts + ((i - ntokens) * varsetsize);
-      cword = *vrow++;
-      b = 0;
-      for (j = ntokens; j < nsyms; j++)
-       {
-         if (cword & (1 << b))
-           {
-             rp = derives[j];
-             while ((ruleno = *rp++) > 0)
-               {
-                 SETBIT (rrow, ruleno);
-               }
-           }
-
-         b++;
-         if (b >= BITS_PER_WORD && j + 1 < nsyms)
-           {
-             cword = *vrow++;
-             b = 0;
-           }
-       }
-
-      rrow += rulesetsize;
-    }
+  for (i = ntokens; i < nsyms; ++i)
+    for (j = ntokens; j < nsyms; ++j)
+      if (bitset_test (FIRSTS (i), j - ntokens))
+       for (k = 0; derives[j][k] > 0; ++k)
+         bitset_set (FDERIVES (i), derives[j][k]);
 
 
-#ifdef DEBUG
-  print_fderives ();
-#endif
+  if (trace_flag)
+    print_fderives ();
 
 
-  XFREE (firsts);
+  bitsetv_free (firsts);
 }
 \f
 
 }
 \f
 
@@ -218,8 +225,7 @@ new_closure (int n)
 {
   itemset = XCALLOC (short, n);
 
 {
   itemset = XCALLOC (short, n);
 
-  rulesetsize = WORDSIZE (nrules + 1);
-  ruleset = XCALLOC (unsigned, rulesetsize);
+  ruleset = bitset_create (nrules + 1, BITSET_FIXED);
 
   set_fderives ();
 }
 
   set_fderives ();
 }
@@ -229,82 +235,53 @@ new_closure (int n)
 void
 closure (short *core, int n)
 {
 void
 closure (short *core, int n)
 {
-  int ruleno;
-  unsigned word;
-  short *csp;
-  unsigned *dsp;
-  unsigned *rsp;
+  /* Index over CORE. */
+  int c;
 
 
-  short *csend;
-  unsigned *rsend;
-  int symbol;
-  int itemno;
+  /* A bit index over RULESET. */
+  int ruleno;
 
 
-  rsp = ruleset;
-  rsend = ruleset + rulesetsize;
-  csend = core + n;
+  if (trace_flag)
+    print_closure ("input", core, n);
 
   if (n == 0)
     {
 
   if (n == 0)
     {
-      dsp = fderives + start_symbol * rulesetsize;
-      while (rsp < rsend)
-       *rsp++ = *dsp++;
+      bitset_copy (ruleset, FDERIVES (start_symbol));
     }
   else
     {
     }
   else
     {
-      while (rsp < rsend)
-       *rsp++ = 0;
-
-      csp = core;
-      while (csp < csend)
-       {
-         symbol = ritem[*csp++];
-         if (ISVAR (symbol))
-           {
-             dsp = fderives + symbol * rulesetsize;
-             rsp = ruleset;
-             while (rsp < rsend)
-               *rsp++ |= *dsp++;
-           }
-       }
+      bitset_zero (ruleset);
+
+      for (c = 0; c < n; ++c)
+       if (ISVAR (ritem[core[c]]))
+         bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
     }
 
     }
 
-  ruleno = 0;
-  itemsetend = itemset;
-  csp = core;
-  rsp = ruleset;
-  while (rsp < rsend)
+  nitemset = 0;
+  c = 0;
+  for (ruleno = 0; ruleno < nrules + 1; ++ruleno)
+    if (bitset_test (ruleset, ruleno))
+      {
+       int itemno = rules[ruleno].rhs;
+       while (c < n && core[c] < itemno)
+         {
+           itemset[nitemset] = core[c];
+           nitemset++;
+           c++;
+         }
+       itemset[nitemset] = itemno;
+       nitemset++;
+      }
+
+  while (c < n)
     {
     {
-      word = *rsp++;
-      if (word == 0)
-       {
-         ruleno += BITS_PER_WORD;
-       }
-      else
-       {
-         int b;
-
-         for (b = 0; b < BITS_PER_WORD; b++)
-           {
-             if (word & (1 << b))
-               {
-                 itemno = rrhs[ruleno];
-                 while (csp < csend && *csp < itemno)
-                   *itemsetend++ = *csp++;
-                 *itemsetend++ = itemno;
-               }
-
-             ruleno++;
-           }
-       }
+      itemset[nitemset] = core[c];
+      nitemset++;
+      c++;
     }
 
     }
 
-  while (csp < csend)
-    *itemsetend++ = *csp++;
-
-#if DEBUG
-  print_closure (n);
-#endif
+  if (trace_flag)
+    print_closure ("output", itemset, nitemset);
 }
 
 
 }
 
 
@@ -312,6 +289,6 @@ void
 free_closure (void)
 {
   XFREE (itemset);
 free_closure (void)
 {
   XFREE (itemset);
-  XFREE (ruleset);
-  XFREE (fderives + ntokens * rulesetsize);
+  bitset_free (ruleset);
+  bitsetv_free (fderives);
 }
 }