aboutsummaryrefslogtreecommitdiffstats
path: root/utils/Burg/closure.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/Burg/closure.c')
-rw-r--r--utils/Burg/closure.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/utils/Burg/closure.c b/utils/Burg/closure.c
new file mode 100644
index 0000000..70e1626
--- /dev/null
+++ b/utils/Burg/closure.c
@@ -0,0 +1,95 @@
+char rcsid_closure[] = "$Id$";
+
+#include <stdio.h>
+#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;
+ }
+ }
+ }
+ }
+}