]> git.saurik.com Git - bison.git/blobdiff - src/nullable.c
* src/LR0.c: Attach shifts to states as soon as they are
[bison.git] / src / nullable.c
index 74164937f7296d020152b99dc04315ff900a9068..8e8809e20b993f6f865aade2202fefe4f5c5e6bf 100644 (file)
@@ -28,6 +28,7 @@
 #include "reader.h"
 #include "types.h"
 #include "gram.h"
+#include "reduce.h"
 #include "nullable.h"
 
 char *nullable = NULL;
@@ -64,11 +65,14 @@ set_nullable (void)
   s1 = s2 = squeue;
 
   rcount = XCALLOC (short, nrules + 1);
-  rsets = XCALLOC (shorts *, nvars) - ntokens;
+
+  /* RITEM contains all the rules, including useless productions.
+     Hence we must allocate room for useless nonterminals too.  */
+  rsets = XCALLOC (shorts *, nvars + nuseless_nonterminals) - 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);
+  relts = XCALLOC (shorts, nitems + nvars + nuseless_nonterminals + 1);
   p = relts;
 
   for (r = ritem; *r; ++r)
@@ -103,23 +107,16 @@ set_nullable (void)
     }
 
   while (s1 < s2)
-    {
-      p = rsets[*s1++];
-      while (p)
-       {
-         int ruleno = p->value;
-         p = p->next;
-         if (--rcount[ruleno] == 0)
+    for (p = rsets[*s1++]; p; p = p->next)
+      {
+       int ruleno = p->value;
+       if (--rcount[ruleno] == 0)
+         if (rule_table[ruleno].useful && !nullable[rule_table[ruleno].lhs])
            {
-             int symbol = rule_table[ruleno].lhs;
-             if (symbol >= 0 && !nullable[symbol])
-               {
-                 nullable[symbol] = 1;
-                 *s2++ = symbol;
-               }
+             nullable[rule_table[ruleno].lhs] = 1;
+             *s2++ = rule_table[ruleno].lhs;
            }
-       }
-    }
+      }
 
   XFREE (squeue);
   XFREE (rcount);