aboutsummaryrefslogtreecommitdiffstats
path: root/utils/Burg/closure.c
blob: 9f355104f03fcfa51cfacf4c087cd8078356c883 (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 = 0;

  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;
        }
      }
    }
  }
}