summaryrefslogtreecommitdiff
path: root/support/tools/Burg/closure.c
blob: 70e16264ebb487901b824b7c510aefd5ff071ebb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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;
				}
			}
		}
	}
}