1*8e022d3cSDag-Erling Smørgrav /* $Id: closure.c,v 1.14 2022/01/09 16:22:58 tom Exp $ */
298e903e7SBaptiste Daroussin
398e903e7SBaptiste Daroussin #include "defs.h"
498e903e7SBaptiste Daroussin
598e903e7SBaptiste Daroussin Value_t *itemset;
698e903e7SBaptiste Daroussin Value_t *itemsetend;
798e903e7SBaptiste Daroussin unsigned *ruleset;
898e903e7SBaptiste Daroussin
998e903e7SBaptiste Daroussin static unsigned *first_derives;
1098e903e7SBaptiste Daroussin static unsigned *EFF;
1198e903e7SBaptiste Daroussin
120c8de5b0SBaptiste Daroussin #ifdef DEBUG
130c8de5b0SBaptiste Daroussin static void print_closure(int);
140c8de5b0SBaptiste Daroussin static void print_EFF(void);
150c8de5b0SBaptiste Daroussin static void print_first_derives(void);
160c8de5b0SBaptiste Daroussin #endif
170c8de5b0SBaptiste Daroussin
1898e903e7SBaptiste Daroussin static void
set_EFF(void)1998e903e7SBaptiste Daroussin set_EFF(void)
2098e903e7SBaptiste Daroussin {
2198e903e7SBaptiste Daroussin unsigned *row;
2298e903e7SBaptiste Daroussin int symbol;
2398e903e7SBaptiste Daroussin int rowsize;
2498e903e7SBaptiste Daroussin int i;
2598e903e7SBaptiste Daroussin int rule;
2698e903e7SBaptiste Daroussin
2798e903e7SBaptiste Daroussin rowsize = WORDSIZE(nvars);
2898e903e7SBaptiste Daroussin EFF = NEW2(nvars * rowsize, unsigned);
2998e903e7SBaptiste Daroussin
3098e903e7SBaptiste Daroussin row = EFF;
3198e903e7SBaptiste Daroussin for (i = start_symbol; i < nsyms; i++)
3298e903e7SBaptiste Daroussin {
33*8e022d3cSDag-Erling Smørgrav Value_t *sp = derives[i];
3498e903e7SBaptiste Daroussin for (rule = *sp; rule > 0; rule = *++sp)
3598e903e7SBaptiste Daroussin {
3698e903e7SBaptiste Daroussin symbol = ritem[rrhs[rule]];
3798e903e7SBaptiste Daroussin if (ISVAR(symbol))
3898e903e7SBaptiste Daroussin {
3998e903e7SBaptiste Daroussin symbol -= start_symbol;
4098e903e7SBaptiste Daroussin SETBIT(row, symbol);
4198e903e7SBaptiste Daroussin }
4298e903e7SBaptiste Daroussin }
4398e903e7SBaptiste Daroussin row += rowsize;
4498e903e7SBaptiste Daroussin }
4598e903e7SBaptiste Daroussin
4698e903e7SBaptiste Daroussin reflexive_transitive_closure(EFF, nvars);
4798e903e7SBaptiste Daroussin
4898e903e7SBaptiste Daroussin #ifdef DEBUG
4998e903e7SBaptiste Daroussin print_EFF();
5098e903e7SBaptiste Daroussin #endif
5198e903e7SBaptiste Daroussin }
5298e903e7SBaptiste Daroussin
5398e903e7SBaptiste Daroussin void
set_first_derives(void)5498e903e7SBaptiste Daroussin set_first_derives(void)
5598e903e7SBaptiste Daroussin {
5698e903e7SBaptiste Daroussin unsigned *rrow;
5798e903e7SBaptiste Daroussin int j;
5898e903e7SBaptiste Daroussin unsigned cword = 0;
590c8de5b0SBaptiste Daroussin Value_t *rp;
6098e903e7SBaptiste Daroussin
6198e903e7SBaptiste Daroussin int rule;
6298e903e7SBaptiste Daroussin int i;
6398e903e7SBaptiste Daroussin int rulesetsize;
6498e903e7SBaptiste Daroussin int varsetsize;
6598e903e7SBaptiste Daroussin
6698e903e7SBaptiste Daroussin rulesetsize = WORDSIZE(nrules);
6798e903e7SBaptiste Daroussin varsetsize = WORDSIZE(nvars);
68*8e022d3cSDag-Erling Smørgrav first_derives = NEW2(nvars * rulesetsize, unsigned);
6998e903e7SBaptiste Daroussin
7098e903e7SBaptiste Daroussin set_EFF();
7198e903e7SBaptiste Daroussin
72*8e022d3cSDag-Erling Smørgrav rrow = first_derives;
7398e903e7SBaptiste Daroussin for (i = start_symbol; i < nsyms; i++)
7498e903e7SBaptiste Daroussin {
75*8e022d3cSDag-Erling Smørgrav unsigned *vrow = EFF + ((i - ntokens) * varsetsize);
76*8e022d3cSDag-Erling Smørgrav unsigned k = BITS_PER_WORD;
77*8e022d3cSDag-Erling Smørgrav
7898e903e7SBaptiste Daroussin for (j = start_symbol; j < nsyms; k++, j++)
7998e903e7SBaptiste Daroussin {
8098e903e7SBaptiste Daroussin if (k >= BITS_PER_WORD)
8198e903e7SBaptiste Daroussin {
8298e903e7SBaptiste Daroussin cword = *vrow++;
8398e903e7SBaptiste Daroussin k = 0;
8498e903e7SBaptiste Daroussin }
8598e903e7SBaptiste Daroussin
86*8e022d3cSDag-Erling Smørgrav if (cword & (1U << k))
8798e903e7SBaptiste Daroussin {
8898e903e7SBaptiste Daroussin rp = derives[j];
8998e903e7SBaptiste Daroussin while ((rule = *rp++) >= 0)
9098e903e7SBaptiste Daroussin {
9198e903e7SBaptiste Daroussin SETBIT(rrow, rule);
9298e903e7SBaptiste Daroussin }
9398e903e7SBaptiste Daroussin }
9498e903e7SBaptiste Daroussin }
9598e903e7SBaptiste Daroussin
9698e903e7SBaptiste Daroussin rrow += rulesetsize;
9798e903e7SBaptiste Daroussin }
9898e903e7SBaptiste Daroussin
9998e903e7SBaptiste Daroussin #ifdef DEBUG
10098e903e7SBaptiste Daroussin print_first_derives();
10198e903e7SBaptiste Daroussin #endif
10298e903e7SBaptiste Daroussin
10398e903e7SBaptiste Daroussin FREE(EFF);
10498e903e7SBaptiste Daroussin }
10598e903e7SBaptiste Daroussin
10698e903e7SBaptiste Daroussin void
closure(Value_t * nucleus,int n)1070c8de5b0SBaptiste Daroussin closure(Value_t *nucleus, int n)
10898e903e7SBaptiste Daroussin {
10998e903e7SBaptiste Daroussin unsigned ruleno;
11098e903e7SBaptiste Daroussin unsigned i;
11198e903e7SBaptiste Daroussin Value_t *csp;
11298e903e7SBaptiste Daroussin unsigned *dsp;
11398e903e7SBaptiste Daroussin unsigned *rsp;
11498e903e7SBaptiste Daroussin int rulesetsize;
11598e903e7SBaptiste Daroussin
11698e903e7SBaptiste Daroussin Value_t *csend;
11798e903e7SBaptiste Daroussin unsigned *rsend;
11898e903e7SBaptiste Daroussin Value_t itemno;
11998e903e7SBaptiste Daroussin
12098e903e7SBaptiste Daroussin rulesetsize = WORDSIZE(nrules);
12198e903e7SBaptiste Daroussin rsend = ruleset + rulesetsize;
12298e903e7SBaptiste Daroussin for (rsp = ruleset; rsp < rsend; rsp++)
12398e903e7SBaptiste Daroussin *rsp = 0;
12498e903e7SBaptiste Daroussin
12598e903e7SBaptiste Daroussin csend = nucleus + n;
12698e903e7SBaptiste Daroussin for (csp = nucleus; csp < csend; ++csp)
12798e903e7SBaptiste Daroussin {
128*8e022d3cSDag-Erling Smørgrav int symbol = ritem[*csp];
129*8e022d3cSDag-Erling Smørgrav
13098e903e7SBaptiste Daroussin if (ISVAR(symbol))
13198e903e7SBaptiste Daroussin {
132*8e022d3cSDag-Erling Smørgrav dsp = first_derives + (symbol - ntokens) * rulesetsize;
13398e903e7SBaptiste Daroussin rsp = ruleset;
13498e903e7SBaptiste Daroussin while (rsp < rsend)
13598e903e7SBaptiste Daroussin *rsp++ |= *dsp++;
13698e903e7SBaptiste Daroussin }
13798e903e7SBaptiste Daroussin }
13898e903e7SBaptiste Daroussin
13998e903e7SBaptiste Daroussin ruleno = 0;
14098e903e7SBaptiste Daroussin itemsetend = itemset;
14198e903e7SBaptiste Daroussin csp = nucleus;
14298e903e7SBaptiste Daroussin for (rsp = ruleset; rsp < rsend; ++rsp)
14398e903e7SBaptiste Daroussin {
144*8e022d3cSDag-Erling Smørgrav unsigned word = *rsp;
145*8e022d3cSDag-Erling Smørgrav
14698e903e7SBaptiste Daroussin if (word)
14798e903e7SBaptiste Daroussin {
14898e903e7SBaptiste Daroussin for (i = 0; i < BITS_PER_WORD; ++i)
14998e903e7SBaptiste Daroussin {
150*8e022d3cSDag-Erling Smørgrav if (word & (1U << i))
15198e903e7SBaptiste Daroussin {
15298e903e7SBaptiste Daroussin itemno = rrhs[ruleno + i];
15398e903e7SBaptiste Daroussin while (csp < csend && *csp < itemno)
15498e903e7SBaptiste Daroussin *itemsetend++ = *csp++;
15598e903e7SBaptiste Daroussin *itemsetend++ = itemno;
15698e903e7SBaptiste Daroussin while (csp < csend && *csp == itemno)
15798e903e7SBaptiste Daroussin ++csp;
15898e903e7SBaptiste Daroussin }
15998e903e7SBaptiste Daroussin }
16098e903e7SBaptiste Daroussin }
16198e903e7SBaptiste Daroussin ruleno += BITS_PER_WORD;
16298e903e7SBaptiste Daroussin }
16398e903e7SBaptiste Daroussin
16498e903e7SBaptiste Daroussin while (csp < csend)
16598e903e7SBaptiste Daroussin *itemsetend++ = *csp++;
16698e903e7SBaptiste Daroussin
16798e903e7SBaptiste Daroussin #ifdef DEBUG
16898e903e7SBaptiste Daroussin print_closure(n);
16998e903e7SBaptiste Daroussin #endif
17098e903e7SBaptiste Daroussin }
17198e903e7SBaptiste Daroussin
17298e903e7SBaptiste Daroussin void
finalize_closure(void)17398e903e7SBaptiste Daroussin finalize_closure(void)
17498e903e7SBaptiste Daroussin {
17598e903e7SBaptiste Daroussin FREE(itemset);
17698e903e7SBaptiste Daroussin FREE(ruleset);
177*8e022d3cSDag-Erling Smørgrav FREE(first_derives);
17898e903e7SBaptiste Daroussin }
17998e903e7SBaptiste Daroussin
18098e903e7SBaptiste Daroussin #ifdef DEBUG
18198e903e7SBaptiste Daroussin
1820c8de5b0SBaptiste Daroussin static void
print_closure(int n)18398e903e7SBaptiste Daroussin print_closure(int n)
18498e903e7SBaptiste Daroussin {
1850c8de5b0SBaptiste Daroussin Value_t *isp;
18698e903e7SBaptiste Daroussin
18798e903e7SBaptiste Daroussin printf("\n\nn = %d\n\n", n);
18898e903e7SBaptiste Daroussin for (isp = itemset; isp < itemsetend; isp++)
18998e903e7SBaptiste Daroussin printf(" %d\n", *isp);
19098e903e7SBaptiste Daroussin }
19198e903e7SBaptiste Daroussin
1920c8de5b0SBaptiste Daroussin static void
print_EFF(void)19398e903e7SBaptiste Daroussin print_EFF(void)
19498e903e7SBaptiste Daroussin {
19598e903e7SBaptiste Daroussin int i, j;
19698e903e7SBaptiste Daroussin unsigned *rowp;
19798e903e7SBaptiste Daroussin unsigned word;
19898e903e7SBaptiste Daroussin unsigned k;
19998e903e7SBaptiste Daroussin
20098e903e7SBaptiste Daroussin printf("\n\nEpsilon Free Firsts\n");
20198e903e7SBaptiste Daroussin
20298e903e7SBaptiste Daroussin for (i = start_symbol; i < nsyms; i++)
20398e903e7SBaptiste Daroussin {
20498e903e7SBaptiste Daroussin printf("\n%s", symbol_name[i]);
20598e903e7SBaptiste Daroussin rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars));
20698e903e7SBaptiste Daroussin word = *rowp++;
20798e903e7SBaptiste Daroussin
20898e903e7SBaptiste Daroussin k = BITS_PER_WORD;
20998e903e7SBaptiste Daroussin for (j = 0; j < nvars; k++, j++)
21098e903e7SBaptiste Daroussin {
21198e903e7SBaptiste Daroussin if (k >= BITS_PER_WORD)
21298e903e7SBaptiste Daroussin {
21398e903e7SBaptiste Daroussin word = *rowp++;
21498e903e7SBaptiste Daroussin k = 0;
21598e903e7SBaptiste Daroussin }
21698e903e7SBaptiste Daroussin
21798e903e7SBaptiste Daroussin if (word & (1 << k))
21898e903e7SBaptiste Daroussin printf(" %s", symbol_name[start_symbol + j]);
21998e903e7SBaptiste Daroussin }
22098e903e7SBaptiste Daroussin }
22198e903e7SBaptiste Daroussin }
22298e903e7SBaptiste Daroussin
2230c8de5b0SBaptiste Daroussin static void
print_first_derives(void)22498e903e7SBaptiste Daroussin print_first_derives(void)
22598e903e7SBaptiste Daroussin {
22698e903e7SBaptiste Daroussin int i;
22798e903e7SBaptiste Daroussin int j;
22898e903e7SBaptiste Daroussin unsigned *rp;
22998e903e7SBaptiste Daroussin unsigned cword = 0;
23098e903e7SBaptiste Daroussin unsigned k;
23198e903e7SBaptiste Daroussin
23298e903e7SBaptiste Daroussin printf("\n\n\nFirst Derives\n");
23398e903e7SBaptiste Daroussin
23498e903e7SBaptiste Daroussin for (i = start_symbol; i < nsyms; i++)
23598e903e7SBaptiste Daroussin {
23698e903e7SBaptiste Daroussin printf("\n%s derives\n", symbol_name[i]);
237*8e022d3cSDag-Erling Smørgrav rp = first_derives + (i - ntokens) * WORDSIZE(nrules);
23898e903e7SBaptiste Daroussin k = BITS_PER_WORD;
23998e903e7SBaptiste Daroussin for (j = 0; j <= nrules; k++, j++)
24098e903e7SBaptiste Daroussin {
24198e903e7SBaptiste Daroussin if (k >= BITS_PER_WORD)
24298e903e7SBaptiste Daroussin {
24398e903e7SBaptiste Daroussin cword = *rp++;
24498e903e7SBaptiste Daroussin k = 0;
24598e903e7SBaptiste Daroussin }
24698e903e7SBaptiste Daroussin
24798e903e7SBaptiste Daroussin if (cword & (1 << k))
24898e903e7SBaptiste Daroussin printf(" %d\n", j);
24998e903e7SBaptiste Daroussin }
25098e903e7SBaptiste Daroussin }
25198e903e7SBaptiste Daroussin
25298e903e7SBaptiste Daroussin fflush(stdout);
25398e903e7SBaptiste Daroussin }
25498e903e7SBaptiste Daroussin
25598e903e7SBaptiste Daroussin #endif
256