]> git.saurik.com Git - bison.git/blobdiff - src/nullable.c
* src/warshall.c (TC, RTC): De-obsfucate (source reduced to 22% of
[bison.git] / src / nullable.c
index 8733bc028c555781053a20774ecce087a7c68b23..8e8809e20b993f6f865aade2202fefe4f5c5e6bf 100644 (file)
@@ -1,5 +1,5 @@
 /* Part of the bison parser generator,
 /* Part of the bison parser generator,
-   Copyright (C) 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 "reader.h"
 #include "types.h"
 #include "gram.h"
 #include "types.h"
 #include "gram.h"
-#include "alloc.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", tags[i], nullable[i] ? "yes" : "no");
+  fputs ("\n\n", out);
+}
+
 void
 set_nullable (void)
 {
   short *r;
   short *s1;
   short *s2;
 void
 set_nullable (void)
 {
   short *r;
   short *s1;
   short *s2;
-  int ruleno;
-  int symbol;
   shorts *p;
 
   short *squeue;
   short *rcount;
   shorts **rsets;
   shorts *relts;
   shorts *p;
 
   short *squeue;
   short *rcount;
   shorts **rsets;
   shorts *relts;
-  char any_tokens;
-  short *r1;
 
 
-#ifdef TRACE
-  fprintf (stderr, _("Entering set_nullable"));
-#endif
+  if (trace_flag)
+    fprintf (stderr, "Entering set_nullable\n");
 
 
-  nullable = NEW2 (nvars, char) - ntokens;
+  nullable = XCALLOC (char, nvars) - ntokens;
 
 
-  squeue = NEW2 (nvars, short);
+  squeue = XCALLOC (short, nvars);
   s1 = s2 = squeue;
 
   s1 = s2 = squeue;
 
-  rcount = NEW2 (nrules + 1, short);
-  rsets = NEW2 (nvars, shorts *) - ntokens;
+  rcount = XCALLOC (short, nrules + 1);
+
+  /* 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?  */
   /* This is said to be more elements than we actually use.
      Supposedly nitems - nrules is enough.
      But why take the risk?  */
-  relts = NEW2 (nitems + nvars + 1, shorts);
+  relts = XCALLOC (shorts, nitems + nvars + nuseless_nonterminals + 1);
   p = relts;
 
   p = relts;
 
-  r = ritem;
-  while (*r)
+  for (r = ritem; *r; ++r)
     {
     {
-      if (*r < 0)
+      /* Walk RITEM to find (i), if there are any tokens in the
+        RHS, and (ii), to find RULENO. */
+      int ruleno;
+      int any_tokens = 0;
+      short *r1;
+      for (r1 = r; *r1 > 0; ++r1)
+       if (ISTOKEN (*r1))
+         any_tokens = 1;
+      ruleno = -*r1;
+
+      /* Examine the RHS of the rule.  */
+      if (!any_tokens)
+       for (/* Nothing. */; *r > 0; ++r)
+         {
+           rcount[ruleno]++;
+           p->next = rsets[*r];
+           p->value = ruleno;
+           rsets[*r] = p;
+           p++;
+         }
+
+      /* Examine its LHS. */
+      if (rule_table[ruleno].useful && !nullable[rule_table[ruleno].lhs])
        {
        {
-         symbol = rlhs[-(*r++)];
-         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))
-               any_tokens = 1;
-           }
-
-         if (!any_tokens)
-           {
-             ruleno = -symbol;
-             r = r1;
-             for (symbol = *r++; symbol > 0; symbol = *r++)
-               {
-                 rcount[ruleno]++;
-                 p->next = rsets[symbol];
-                 p->value = ruleno;
-                 rsets[symbol] = p;
-                 p++;
-               }
-           }
-       }
+         nullable[rule_table[ruleno].lhs] = 1;
+         *s2++ = rule_table[ruleno].lhs;
+        }
     }
 
   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)
+      {
+       int ruleno = p->value;
+       if (--rcount[ruleno] == 0)
+         if (rule_table[ruleno].useful && !nullable[rule_table[ruleno].lhs])
            {
            {
-             symbol = rlhs[ruleno];
-             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);
+  XFREE (rsets + ntokens);
+  XFREE (relts);
 
 
-  FREE (squeue);
-  FREE (rcount);
-  FREE (rsets + ntokens);
-  FREE (relts);
+  if (trace_flag)
+    nullable_print (stderr);
 }
 
 
 void
 free_nullable (void)
 {
 }
 
 
 void
 free_nullable (void)
 {
-  FREE (nullable + ntokens);
+  XFREE (nullable + ntokens);
 }
 }