]> git.saurik.com Git - bison.git/blobdiff - src/nullable.c
* src/LR0.c (state_list_t, state_list_append): New.
[bison.git] / src / nullable.c
index 6c60f0fdb395d950d22321e050c1583c242efa64..42e398b34624b92f865f1ba86019bd5385ef30ca 100644 (file)
@@ -1,5 +1,5 @@
 /* Part of the bison parser generator,
 /* Part of the bison parser generator,
-   Copyright 1984, 1989, 2000 Free Software Foundation, Inc.
+   Copyright 1984, 1989, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
    do so.  */
 
 #include "system.h"
    do so.  */
 
 #include "system.h"
+#include "getargs.h"
+#include "symtab.h"
 #include "types.h"
 #include "gram.h"
 #include "types.h"
 #include "gram.h"
+#include "reduce.h"
 #include "nullable.h"
 
 char *nullable = NULL;
 
 #include "nullable.h"
 
 char *nullable = NULL;
 
+static void
+nullable_print (FILE *out)
+{
+  int i;
+  fputs ("NULLABLE\n", out);
+  for (i = ntokens; i < nsyms; i++)
+    fprintf (out, "\t%s: %s\n", symbols[i]->tag, nullable[i] ? "yes" : "no");
+  fputs ("\n\n", out);
+}
+
 void
 set_nullable (void)
 {
 void
 set_nullable (void)
 {
-  short *r;
-  short *s1;
-  short *s2;
   int ruleno;
   int ruleno;
-  int symbol;
+  symbol_number_t *s1;
+  symbol_number_t *s2;
   shorts *p;
 
   shorts *p;
 
-  short *squeue;
-  short *rcount;
-  shorts **rsets;
-  shorts *relts;
-  char any_tokens;
-  short *r1;
+  symbol_number_t *squeue = XCALLOC (symbol_number_t, nvars);
+  short *rcount = XCALLOC (short, nrules + 1);
+  /* RITEM contains all the rules, including useless productions.
+     Hence we must allocate room for useless nonterminals too.  */
+  shorts **rsets = XCALLOC (shorts *, nvars) - ntokens;
+  /* This is said to be more elements than we actually use.
+     Supposedly NRITEMS - NRULES is enough.  But why take the risk?  */
+  shorts *relts = XCALLOC (shorts, nritems + nvars + 1);
 
 
-#ifdef TRACE
-  fprintf (stderr, _("Entering set_nullable"));
-#endif
+  if (trace_flag)
+    fprintf (stderr, "Entering set_nullable\n");
 
   nullable = XCALLOC (char, nvars) - ntokens;
 
 
   nullable = XCALLOC (char, nvars) - ntokens;
 
-  squeue = XCALLOC (short, nvars);
   s1 = s2 = squeue;
   s1 = s2 = squeue;
-
-  rcount = XCALLOC (short, nrules + 1);
-  rsets = XCALLOC (shorts *, nvars) - ntokens;
-  /* This is said to be more elements than we actually use.
-     Supposedly nitems - nrules is enough.
-     But why take the risk?  */
-  relts = XCALLOC (shorts, nitems + nvars + 1);
   p = relts;
 
   p = relts;
 
-  r = ritem;
-  while (*r)
-    {
-      if (*r < 0)
-       {
-         symbol = rule_table[-(*r++)].lhs;
-         if (symbol >= 0 && !nullable[symbol])
-           {
-             nullable[symbol] = 1;
-             *s2++ = symbol;
-           }
-       }
-      else
-       {
-         r1 = r;
-         any_tokens = 0;
-         for (symbol = *r++; symbol > 0; symbol = *r++)
-           {
-             if (ISTOKEN (symbol))
+  for (ruleno = 1; ruleno < nrules + 1; ++ruleno)
+    if (rules[ruleno].useful)
+      {
+       if (rules[ruleno].rhs[0] >= 0)
+         {
+           /* This rule has a non empty RHS. */
+           item_number_t *r;
+           int any_tokens = 0;
+           for (r = rules[ruleno].rhs; *r >= 0; ++r)
+             if (ISTOKEN (*r))
                any_tokens = 1;
                any_tokens = 1;
-           }
 
 
-         if (!any_tokens)
-           {
-             ruleno = -symbol;
-             r = r1;
-             for (symbol = *r++; symbol > 0; symbol = *r++)
+           /* This rule has only nonterminals: schedule it for the second
+              pass.  */
+           if (!any_tokens)
+             for (r = rules[ruleno].rhs; *r >= 0; ++r)
                {
                  rcount[ruleno]++;
                {
                  rcount[ruleno]++;
-                 p->next = rsets[symbol];
+                 p->next = rsets[*r];
                  p->value = ruleno;
                  p->value = ruleno;
-                 rsets[symbol] = p;
+                 rsets[*r] = p;
                  p++;
                }
                  p++;
                }
-           }
-       }
-    }
+         }
+       else
+         {
+           /* This rule has an empty RHS. */
+           assert (rules[ruleno].rhs[0] == -ruleno);
+           if (rules[ruleno].useful && !nullable[rules[ruleno].lhs->number])
+             {
+               nullable[rules[ruleno].lhs->number] = 1;
+               *s2++ = rules[ruleno].lhs->number;
+             }
+         }
+      }
 
   while (s1 < s2)
 
   while (s1 < s2)
-    {
-      p = rsets[*s1++];
-      while (p)
-       {
-         ruleno = p->value;
-         p = p->next;
-         if (--rcount[ruleno] == 0)
+    for (p = rsets[*s1++]; p; p = p->next)
+      {
+       ruleno = p->value;
+       if (--rcount[ruleno] == 0)
+         if (rules[ruleno].useful && !nullable[rules[ruleno].lhs->number])
            {
            {
-             symbol = rule_table[ruleno].lhs;
-             if (symbol >= 0 && !nullable[symbol])
-               {
-                 nullable[symbol] = 1;
-                 *s2++ = symbol;
-               }
+             nullable[rules[ruleno].lhs->number] = 1;
+             *s2++ = rules[ruleno].lhs->number;
            }
            }
-       }
-    }
+      }
 
   XFREE (squeue);
   XFREE (rcount);
   XFREE (rsets + ntokens);
   XFREE (relts);
 
   XFREE (squeue);
   XFREE (rcount);
   XFREE (rsets + ntokens);
   XFREE (relts);
+
+  if (trace_flag)
+    nullable_print (stderr);
 }
 
 
 }