Default paths were computed wrong. This is corrected.

This commit is contained in:
ceriel 1987-03-16 22:26:03 +00:00
parent d52e25949a
commit 9a07fc841f

View file

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