xref: /freebsd-src/contrib/byacc/closure.c (revision 8e022d3cdea10ee1039a632f670c27fd93f65625)
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