]> git.saurik.com Git - bison.git/blobdiff - src/nullable.c
Regen.
[bison.git] / src / nullable.c
index 2797180c4496e51341627394bbb84bb352c36831..c0b60f64d40235e653e2f9b7033030341d0d0580 100644 (file)
@@ -1,5 +1,5 @@
 /* Part of the bison parser generator,
 /* Part of the bison parser generator,
-   Copyright 1984, 1989, 2000, 2001 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.
 
 
 #include "system.h"
 #include "getargs.h"
 
 #include "system.h"
 #include "getargs.h"
-#include "reader.h"
-#include "types.h"
+#include "symtab.h"
 #include "gram.h"
 #include "reduce.h"
 #include "nullable.h"
 
 #include "gram.h"
 #include "reduce.h"
 #include "nullable.h"
 
-char *nullable = NULL;
+/* Linked list of rules.  */
+typedef struct rule_list_s
+{
+  struct rule_list_s *next;
+  rule_t *value;
+} rule_list_t;
+
+bool *nullable = NULL;
 
 static void
 nullable_print (FILE *out)
 
 static void
 nullable_print (FILE *out)
@@ -39,104 +45,93 @@ nullable_print (FILE *out)
   int i;
   fputs ("NULLABLE\n", out);
   for (i = ntokens; i < nsyms; i++)
   int i;
   fputs ("NULLABLE\n", out);
   for (i = ntokens; i < nsyms; i++)
-    fprintf (out, "\t%s: %s\n", tags[i], nullable[i] ? "yes" : "no");
+    fprintf (out, "\t%s: %s\n", symbols[i]->tag, nullable[i] ? "yes" : "no");
   fputs ("\n\n", out);
 }
 
 void
   fputs ("\n\n", out);
 }
 
 void
-set_nullable (void)
+nullable_compute (void)
 {
 {
-  short *r;
-  short *s1;
-  short *s2;
-  shorts *p;
-
-  short *squeue;
-  short *rcount;
-  shorts **rsets;
-  shorts *relts;
-
-  if (trace_flag)
-    fprintf (stderr, "Entering set_nullable\n");
-
-  nullable = XCALLOC (char, nvars) - ntokens;
-
-  squeue = XCALLOC (short, nvars);
-  s1 = s2 = squeue;
-
-  rcount = XCALLOC (short, nrules + 1);
+  rule_number_t ruleno;
+  symbol_number_t *s1;
+  symbol_number_t *s2;
+  rule_list_t *p;
 
 
+  symbol_number_t *squeue = XCALLOC (symbol_number_t, nvars);
+  short *rcount = XCALLOC (short, nrules);
   /* RITEM contains all the rules, including useless productions.
      Hence we must allocate room for useless nonterminals too.  */
   /* RITEM contains all the rules, including useless productions.
      Hence we must allocate room for useless nonterminals too.  */
-  rsets = XCALLOC (shorts *, nvars + nuseless_nonterminals) - ntokens;
+  rule_list_t **rsets = XCALLOC (rule_list_t *, nvars) - ntokens;
   /* This is said to be more elements than we actually use.
   /* 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 + nuseless_nonterminals + 1);
+     Supposedly NRITEMS - NRULES is enough.  But why take the risk?  */
+  rule_list_t *relts = XCALLOC (rule_list_t, nritems + nvars + 1);
+
+  nullable = XCALLOC (bool, nvars) - ntokens;
+
+  s1 = s2 = squeue;
   p = relts;
 
   p = relts;
 
-  for (r = ritem; *r; ++r)
-    {
-      /* 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)
+  for (ruleno = 0; ruleno < nrules; ++ruleno)
+    if (rules[ruleno].useful)
+      {
+       rule_t *rule = &rules[ruleno];
+       if (rule->rhs[0] >= 0)
          {
          {
-           rcount[ruleno]++;
-           p->next = rsets[*r];
-           p->value = ruleno;
-           rsets[*r] = p;
-           p++;
+           /* This rule has a non empty RHS. */
+           item_number_t *r = NULL;
+           int any_tokens = 0;
+           for (r = rule->rhs; *r >= 0; ++r)
+             if (ISTOKEN (*r))
+               any_tokens = 1;
+
+           /* This rule has only nonterminals: schedule it for the second
+              pass.  */
+           if (!any_tokens)
+             for (r = rule->rhs; *r >= 0; ++r)
+               {
+                 rcount[ruleno]++;
+                 p->next = rsets[*r];
+                 p->value = rule;
+                 rsets[*r] = p;
+                 p++;
+               }
          }
          }
-
-      /* Examine its LHS. */
-      if (rule_table[ruleno].useful && !nullable[rule_table[ruleno].lhs])
-       {
-         nullable[rule_table[ruleno].lhs] = 1;
-         *s2++ = rule_table[ruleno].lhs;
-        }
-    }
+       else
+         {
+           /* This rule has an empty RHS. */
+           assert (item_number_as_rule_number (rule->rhs[0]) == ruleno);
+           if (rule->useful && !nullable[rule->lhs->number])
+             {
+               nullable[rule->lhs->number] = 1;
+               *s2++ = rule->lhs->number;
+             }
+         }
+      }
 
   while (s1 < s2)
 
   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)
+      {
+       rule_t *rule = p->value;
+       if (--rcount[rule->number] == 0)
+         if (rule->useful && !nullable[rule->lhs->number])
            {
            {
-             int symbol = rule_table[ruleno].lhs;
-             if (symbol >= 0 && !nullable[symbol])
-               {
-                 nullable[symbol] = 1;
-                 *s2++ = symbol;
-               }
+             nullable[rule->lhs->number] = 1;
+             *s2++ = rule->lhs->number;
            }
            }
-       }
-    }
+      }
 
   XFREE (squeue);
   XFREE (rcount);
   XFREE (rsets + ntokens);
   XFREE (relts);
 
 
   XFREE (squeue);
   XFREE (rcount);
   XFREE (rsets + ntokens);
   XFREE (relts);
 
-  if (trace_flag)
+  if (trace_flag & trace_sets)
     nullable_print (stderr);
 }
 
 
 void
     nullable_print (stderr);
 }
 
 
 void
-free_nullable (void)
+nullable_free (void)
 {
   XFREE (nullable + ntokens);
 }
 {
   XFREE (nullable + ntokens);
 }