Default paths were computed wrong. This is corrected.
authorceriel <none@none>
Mon, 16 Mar 1987 22:26:03 +0000 (22:26 +0000)
committerceriel <none@none>
Mon, 16 Mar 1987 22:26:03 +0000 (22:26 +0000)
util/LLgen/src/compute.c

index 71b1b32..d576a04 100644 (file)
@@ -22,9 +22,7 @@
 # include "extern.h"
 # include "sets.h"
 # include "assert.h"
-# ifndef NDEBUG
 # include "io.h"
-# endif
 
 # ifndef NORCSID
 static string rcsid = "$Header$";
@@ -53,7 +51,6 @@ STATIC int nfollow();
 STATIC follow();
 STATIC co_dirsymb();
 STATIC co_others();
-STATIC int ncomplength();
 STATIC do_lengthcomp();
 STATIC complength();
 STATIC add();
@@ -471,6 +468,18 @@ co_others(p) register p_gram p; {
 static p_length length;
 # define INFINITY 32767
 
+STATIC
+ncomplength(p)
+       register p_nont p;
+{
+       register p_length pl = &length[p - nonterms];
+       int x = pl->cnt;
+
+       pl->cnt = -1;
+       complength(p->n_rule, pl);
+       return pl->cnt < INFINITY && x == INFINITY;
+}
+
 STATIC
 do_lengthcomp() {
        /*
@@ -484,13 +493,17 @@ do_lengthcomp() {
         */
        register p_length pl;
        register p_nont p;
+       register p_start st;
+       int change = 1;
        p_mem alloc();
 
        length = (p_length) alloc((unsigned) (nnonterms * sizeof(*length)));
        for (pl = &length[nnonterms-1]; pl >= length; pl--) {
                pl->val = pl->cnt = INFINITY;
        }
+
        co_trans(ncomplength);
+
        pl = length;
        for (p = nonterms; p < maxnt; p++, pl++) {
                if (pl->cnt == INFINITY) {
@@ -501,54 +514,45 @@ do_lengthcomp() {
        free ((p_mem) length);
 }
 
-STATIC int
-ncomplength(p) register p_nont p; {
-       register p_length l;
-
-       l = &length[p - nonterms];
-       if (l->cnt == INFINITY) {
-               complength(p->n_rule, l);
-               if (l->cnt != INFINITY) return 1;
-       }
-       return 0;
-}
-
 STATIC
-complength(p,le) register p_gram p; register p_length le; {
+complength(p,le) register p_gram p; p_length le; {
        /*
         * Walk grammar rule p, computing minimum lengths
         */
        register p_link l;
        register p_term q;
        t_length i;
+       t_length X;
 
-       le->cnt = 0;
-       le->val = 0;
+       X.cnt = 0;
+       X.val = 0;
        for (;;) {
                switch (g_gettype(p)) {
-                 case EORULE :
-                       return;
                  case LITERAL :
                  case TERMINAL :
-                       if (!le->cnt) add(le, 1, g_getcont(p));
-                       else add(le, 1, 0);
+                       if (!X.cnt) add(&X, 1, g_getcont(p));
+                       else add(&X, 1, 0);
                        break;
                  case ALTERNATION :
 
-                       le->cnt = INFINITY;
-                       le->val = INFINITY;
+                       X.cnt = INFINITY;
+                       X.val = INFINITY;
                        while (g_gettype(p) != EORULE) {
                                l = &links[g_getcont(p)];
                                complength(l->l_rule,&i);
                                if (l->l_flag & DEF) {
-                                       *le = i;
-                                       return;
+                                       X = i;
+                                       break;
                                }
-                               if (compare(&i, le) < 0) {
-                                       *le = i;
+                               if (compare(&i, &X) < 0) {
+                                       X = i;
                                }
                                p++;
                        }
+                       /* Fall through */
+                 case EORULE :
+                       le->cnt = X.cnt;
+                       le->val = X.val;
                        return;
                  case TERM : {
                        register int rep;
@@ -558,28 +562,35 @@ complength(p,le) register p_gram p; register p_length le; {
                        if ((q->t_flags&PERSISTENT) || 
                            rep==FIXED || rep==PLUS) {
                                complength(q->t_rule,&i);
-                               add(le, i.cnt, i.val);
-                               if (i.cnt == 0) le->val += ntokens;
+                               add(&X, i.cnt, i.val);
+                               if (i.cnt == 0) X.val += ntokens;
                                if (rep == FIXED && r_getnum(q) > 0) {
                                        for (rep = r_getnum(q) - 1;
                                             rep > 0; rep--) {
-                                               add(le, i.cnt, i.val);
+                                               add(&X, i.cnt, i.val);
                                        }
                                }
                        }
                        else {
                                /* Empty producing term on this path */
-                                le->val += ntokens;
+                                X.val += ntokens;
                        }
                        break; }
                  case NONTERM : {
-                       register p_length temp;
-
-                       temp = &length[g_getnont(p)];
-                       add(le, temp->cnt, temp->val);
-                       if (temp->cnt == 0) {
+                       int nn = g_getnont(p);
+                       register p_length pl = &length[nn];
+                       int x = pl->cnt;
+
+                       if (x == INFINITY) {
+                               pl->cnt = -1;
+                               complength(nonterms[nn].n_rule,pl);
+                               x = pl->cnt;
+                       }
+                       else if (x == -1) x = INFINITY;
+                       add(&X, x, pl->val);
+                       if (x == 0) {
                                /* Empty producing nonterminal */
-                               le->val += ntokens;
+                               X.val += ntokens;
                        }}
                }
                p++;
@@ -589,7 +600,7 @@ complength(p,le) register p_gram p; register p_length le; {
 STATIC
 add(a, c, v) register p_length a; {
 
-       if (c == INFINITY) {
+       if (a->cnt == INFINITY || c == INFINITY) {
                a->cnt = INFINITY;
                return;
        }