char rcsid_closure[] = "$Id$"; #include #include "b.h" int prevent_divergence = 0; List chainrules; void findChainRules() { List pl; assert(!chainrules); for (pl = rules; pl; pl = pl->next) { Rule p = (Rule) pl->x; if (!p->pat->op) { chainrules = newList(p, chainrules); } else { p->pat->op->table->rules = newList(p, p->pat->op->table->rules); addRelevant(p->pat->op->table->relevant, p->lhs->num); } } } void zero(t) Item_Set t; { int i; DeltaCost base; int exists; int base_nt; assert(!t->closed); ZEROCOST(base); exists = 0; for (i = 0; i < max_nonterminal; i++) { if (t->virgin[i].rule) { if (exists) { if (LESSCOST(t->virgin[i].delta, base)) { ASSIGNCOST(base, t->virgin[i].delta); base_nt = i; } } else { ASSIGNCOST(base, t->virgin[i].delta); exists = 1; base_nt = i; } } } if (!exists) { return; } for (i = 0; i < max_nonterminal; i++) { if (t->virgin[i].rule) { MINUSCOST(t->virgin[i].delta, base); } NODIVERGE(t->virgin[i].delta, t, i, base_nt); } } void closure(t) Item_Set t; { int changes; List pl; assert(!t->closed); t->closed = itemArrayCopy(t->virgin); changes = 1; while (changes) { changes = 0; for (pl = chainrules; pl; pl = pl->next) { Rule p = (Rule) pl->x; register Item *rhs_item = &t->closed[p->pat->children[0]->num]; if (rhs_item->rule) { /* rhs is active */ DeltaCost dc; register Item *lhs_item = &t->closed[p->lhs->num]; ASSIGNCOST(dc, rhs_item->delta); ADDCOST(dc, p->delta); if (LESSCOST(dc, lhs_item->delta) || !lhs_item->rule) { ASSIGNCOST(lhs_item->delta, dc); lhs_item->rule = p; changes = 1; } } } } }