xref: /freebsd/contrib/byacc/lr0.c (revision 8e022d3cdea10ee1039a632f670c27fd93f65625)
1*8e022d3cSDag-Erling Smørgrav /* $Id: lr0.c,v 1.21 2021/05/20 23:57:23 tom Exp $ */
298e903e7SBaptiste Daroussin 
398e903e7SBaptiste Daroussin #include "defs.h"
498e903e7SBaptiste Daroussin 
598e903e7SBaptiste Daroussin static core *new_state(int symbol);
698e903e7SBaptiste Daroussin static Value_t get_state(int symbol);
798e903e7SBaptiste Daroussin static void allocate_itemsets(void);
898e903e7SBaptiste Daroussin static void allocate_storage(void);
998e903e7SBaptiste Daroussin static void append_states(void);
1098e903e7SBaptiste Daroussin static void free_storage(void);
1198e903e7SBaptiste Daroussin static void generate_states(void);
1298e903e7SBaptiste Daroussin static void initialize_states(void);
1398e903e7SBaptiste Daroussin static void new_itemsets(void);
1498e903e7SBaptiste Daroussin static void save_reductions(void);
1598e903e7SBaptiste Daroussin static void save_shifts(void);
1698e903e7SBaptiste Daroussin static void set_derives(void);
1798e903e7SBaptiste Daroussin static void set_nullable(void);
1898e903e7SBaptiste Daroussin 
19*8e022d3cSDag-Erling Smørgrav Value_t nstates;
2098e903e7SBaptiste Daroussin core *first_state;
2198e903e7SBaptiste Daroussin shifts *first_shift;
2298e903e7SBaptiste Daroussin reductions *first_reduction;
2398e903e7SBaptiste Daroussin 
2498e903e7SBaptiste Daroussin static core **state_set;
2598e903e7SBaptiste Daroussin static core *this_state;
2698e903e7SBaptiste Daroussin static core *last_state;
2798e903e7SBaptiste Daroussin static shifts *last_shift;
2898e903e7SBaptiste Daroussin static reductions *last_reduction;
2998e903e7SBaptiste Daroussin 
3098e903e7SBaptiste Daroussin static int nshifts;
310c8de5b0SBaptiste Daroussin static Value_t *shift_symbol;
3298e903e7SBaptiste Daroussin 
330f86d14eSJung-uk Kim static Value_t *rules;
340f86d14eSJung-uk Kim 
3598e903e7SBaptiste Daroussin static Value_t *redset;
3698e903e7SBaptiste Daroussin static Value_t *shiftset;
3798e903e7SBaptiste Daroussin 
3898e903e7SBaptiste Daroussin static Value_t **kernel_base;
3998e903e7SBaptiste Daroussin static Value_t **kernel_end;
4098e903e7SBaptiste Daroussin static Value_t *kernel_items;
4198e903e7SBaptiste Daroussin 
4298e903e7SBaptiste Daroussin static void
allocate_itemsets(void)4398e903e7SBaptiste Daroussin allocate_itemsets(void)
4498e903e7SBaptiste Daroussin {
450c8de5b0SBaptiste Daroussin     Value_t *itemp;
460c8de5b0SBaptiste Daroussin     Value_t *item_end;
4798e903e7SBaptiste Daroussin     int i;
4898e903e7SBaptiste Daroussin     int count;
4998e903e7SBaptiste Daroussin     int max;
500c8de5b0SBaptiste Daroussin     Value_t *symbol_count;
5198e903e7SBaptiste Daroussin 
5298e903e7SBaptiste Daroussin     count = 0;
530c8de5b0SBaptiste Daroussin     symbol_count = NEW2(nsyms, Value_t);
5498e903e7SBaptiste Daroussin 
5598e903e7SBaptiste Daroussin     item_end = ritem + nitems;
5698e903e7SBaptiste Daroussin     for (itemp = ritem; itemp < item_end; itemp++)
5798e903e7SBaptiste Daroussin     {
58*8e022d3cSDag-Erling Smørgrav 	int symbol = *itemp;
59*8e022d3cSDag-Erling Smørgrav 
6098e903e7SBaptiste Daroussin 	if (symbol >= 0)
6198e903e7SBaptiste Daroussin 	{
6298e903e7SBaptiste Daroussin 	    count++;
6398e903e7SBaptiste Daroussin 	    symbol_count[symbol]++;
6498e903e7SBaptiste Daroussin 	}
6598e903e7SBaptiste Daroussin     }
6698e903e7SBaptiste Daroussin 
670c8de5b0SBaptiste Daroussin     kernel_base = NEW2(nsyms, Value_t *);
680c8de5b0SBaptiste Daroussin     kernel_items = NEW2(count, Value_t);
6998e903e7SBaptiste Daroussin 
7098e903e7SBaptiste Daroussin     count = 0;
7198e903e7SBaptiste Daroussin     max = 0;
7298e903e7SBaptiste Daroussin     for (i = 0; i < nsyms; i++)
7398e903e7SBaptiste Daroussin     {
7498e903e7SBaptiste Daroussin 	kernel_base[i] = kernel_items + count;
7598e903e7SBaptiste Daroussin 	count += symbol_count[i];
7698e903e7SBaptiste Daroussin 	if (max < symbol_count[i])
7798e903e7SBaptiste Daroussin 	    max = symbol_count[i];
7898e903e7SBaptiste Daroussin     }
7998e903e7SBaptiste Daroussin 
8098e903e7SBaptiste Daroussin     shift_symbol = symbol_count;
810c8de5b0SBaptiste Daroussin     kernel_end = NEW2(nsyms, Value_t *);
8298e903e7SBaptiste Daroussin }
8398e903e7SBaptiste Daroussin 
8498e903e7SBaptiste Daroussin static void
allocate_storage(void)8598e903e7SBaptiste Daroussin allocate_storage(void)
8698e903e7SBaptiste Daroussin {
8798e903e7SBaptiste Daroussin     allocate_itemsets();
880c8de5b0SBaptiste Daroussin     shiftset = NEW2(nsyms, Value_t);
890c8de5b0SBaptiste Daroussin     redset = NEW2(nrules + 1, Value_t);
9098e903e7SBaptiste Daroussin     state_set = NEW2(nitems, core *);
9198e903e7SBaptiste Daroussin }
9298e903e7SBaptiste Daroussin 
9398e903e7SBaptiste Daroussin static void
append_states(void)9498e903e7SBaptiste Daroussin append_states(void)
9598e903e7SBaptiste Daroussin {
9698e903e7SBaptiste Daroussin     int i;
9798e903e7SBaptiste Daroussin     Value_t symbol;
9898e903e7SBaptiste Daroussin 
9998e903e7SBaptiste Daroussin #ifdef	TRACE
10098e903e7SBaptiste Daroussin     fprintf(stderr, "Entering append_states()\n");
10198e903e7SBaptiste Daroussin #endif
10298e903e7SBaptiste Daroussin     for (i = 1; i < nshifts; i++)
10398e903e7SBaptiste Daroussin     {
104*8e022d3cSDag-Erling Smørgrav 	int j = i;
105*8e022d3cSDag-Erling Smørgrav 
10698e903e7SBaptiste Daroussin 	symbol = shift_symbol[i];
10798e903e7SBaptiste Daroussin 	while (j > 0 && shift_symbol[j - 1] > symbol)
10898e903e7SBaptiste Daroussin 	{
10998e903e7SBaptiste Daroussin 	    shift_symbol[j] = shift_symbol[j - 1];
11098e903e7SBaptiste Daroussin 	    j--;
11198e903e7SBaptiste Daroussin 	}
11298e903e7SBaptiste Daroussin 	shift_symbol[j] = symbol;
11398e903e7SBaptiste Daroussin     }
11498e903e7SBaptiste Daroussin 
11598e903e7SBaptiste Daroussin     for (i = 0; i < nshifts; i++)
11698e903e7SBaptiste Daroussin     {
11798e903e7SBaptiste Daroussin 	symbol = shift_symbol[i];
11898e903e7SBaptiste Daroussin 	shiftset[i] = get_state(symbol);
11998e903e7SBaptiste Daroussin     }
12098e903e7SBaptiste Daroussin }
12198e903e7SBaptiste Daroussin 
12298e903e7SBaptiste Daroussin static void
free_storage(void)12398e903e7SBaptiste Daroussin free_storage(void)
12498e903e7SBaptiste Daroussin {
12598e903e7SBaptiste Daroussin     FREE(shift_symbol);
12698e903e7SBaptiste Daroussin     FREE(redset);
12798e903e7SBaptiste Daroussin     FREE(shiftset);
12898e903e7SBaptiste Daroussin     FREE(kernel_base);
12998e903e7SBaptiste Daroussin     FREE(kernel_end);
13098e903e7SBaptiste Daroussin     FREE(kernel_items);
13198e903e7SBaptiste Daroussin     FREE(state_set);
13298e903e7SBaptiste Daroussin }
13398e903e7SBaptiste Daroussin 
13498e903e7SBaptiste Daroussin static void
generate_states(void)13598e903e7SBaptiste Daroussin generate_states(void)
13698e903e7SBaptiste Daroussin {
13798e903e7SBaptiste Daroussin     allocate_storage();
1380c8de5b0SBaptiste Daroussin     itemset = NEW2(nitems, Value_t);
13998e903e7SBaptiste Daroussin     ruleset = NEW2(WORDSIZE(nrules), unsigned);
14098e903e7SBaptiste Daroussin     set_first_derives();
14198e903e7SBaptiste Daroussin     initialize_states();
14298e903e7SBaptiste Daroussin 
14398e903e7SBaptiste Daroussin     while (this_state)
14498e903e7SBaptiste Daroussin     {
14598e903e7SBaptiste Daroussin 	closure(this_state->items, this_state->nitems);
14698e903e7SBaptiste Daroussin 	save_reductions();
14798e903e7SBaptiste Daroussin 	new_itemsets();
14898e903e7SBaptiste Daroussin 	append_states();
14998e903e7SBaptiste Daroussin 
15098e903e7SBaptiste Daroussin 	if (nshifts > 0)
15198e903e7SBaptiste Daroussin 	    save_shifts();
15298e903e7SBaptiste Daroussin 
15398e903e7SBaptiste Daroussin 	this_state = this_state->next;
15498e903e7SBaptiste Daroussin     }
15598e903e7SBaptiste Daroussin 
15698e903e7SBaptiste Daroussin     free_storage();
15798e903e7SBaptiste Daroussin }
15898e903e7SBaptiste Daroussin 
15998e903e7SBaptiste Daroussin static Value_t
get_state(int symbol)16098e903e7SBaptiste Daroussin get_state(int symbol)
16198e903e7SBaptiste Daroussin {
16298e903e7SBaptiste Daroussin     int key;
1630c8de5b0SBaptiste Daroussin     Value_t *isp1;
1640c8de5b0SBaptiste Daroussin     Value_t *iend;
16598e903e7SBaptiste Daroussin     core *sp;
16698e903e7SBaptiste Daroussin     int n;
16798e903e7SBaptiste Daroussin 
16898e903e7SBaptiste Daroussin #ifdef	TRACE
16998e903e7SBaptiste Daroussin     fprintf(stderr, "Entering get_state(%d)\n", symbol);
17098e903e7SBaptiste Daroussin #endif
17198e903e7SBaptiste Daroussin 
17298e903e7SBaptiste Daroussin     isp1 = kernel_base[symbol];
17398e903e7SBaptiste Daroussin     iend = kernel_end[symbol];
17498e903e7SBaptiste Daroussin     n = (int)(iend - isp1);
17598e903e7SBaptiste Daroussin 
17698e903e7SBaptiste Daroussin     key = *isp1;
17798e903e7SBaptiste Daroussin     assert(0 <= key && key < nitems);
17898e903e7SBaptiste Daroussin     sp = state_set[key];
17998e903e7SBaptiste Daroussin     if (sp)
18098e903e7SBaptiste Daroussin     {
181*8e022d3cSDag-Erling Smørgrav 	int found = 0;
182*8e022d3cSDag-Erling Smørgrav 
18398e903e7SBaptiste Daroussin 	while (!found)
18498e903e7SBaptiste Daroussin 	{
18598e903e7SBaptiste Daroussin 	    if (sp->nitems == n)
18698e903e7SBaptiste Daroussin 	    {
187*8e022d3cSDag-Erling Smørgrav 		Value_t *isp2;
188*8e022d3cSDag-Erling Smørgrav 
18998e903e7SBaptiste Daroussin 		found = 1;
19098e903e7SBaptiste Daroussin 		isp1 = kernel_base[symbol];
19198e903e7SBaptiste Daroussin 		isp2 = sp->items;
19298e903e7SBaptiste Daroussin 
19398e903e7SBaptiste Daroussin 		while (found && isp1 < iend)
19498e903e7SBaptiste Daroussin 		{
19598e903e7SBaptiste Daroussin 		    if (*isp1++ != *isp2++)
19698e903e7SBaptiste Daroussin 			found = 0;
19798e903e7SBaptiste Daroussin 		}
19898e903e7SBaptiste Daroussin 	    }
19998e903e7SBaptiste Daroussin 
20098e903e7SBaptiste Daroussin 	    if (!found)
20198e903e7SBaptiste Daroussin 	    {
20298e903e7SBaptiste Daroussin 		if (sp->link)
20398e903e7SBaptiste Daroussin 		{
20498e903e7SBaptiste Daroussin 		    sp = sp->link;
20598e903e7SBaptiste Daroussin 		}
20698e903e7SBaptiste Daroussin 		else
20798e903e7SBaptiste Daroussin 		{
20898e903e7SBaptiste Daroussin 		    sp = sp->link = new_state(symbol);
20998e903e7SBaptiste Daroussin 		    found = 1;
21098e903e7SBaptiste Daroussin 		}
21198e903e7SBaptiste Daroussin 	    }
21298e903e7SBaptiste Daroussin 	}
21398e903e7SBaptiste Daroussin     }
21498e903e7SBaptiste Daroussin     else
21598e903e7SBaptiste Daroussin     {
21698e903e7SBaptiste Daroussin 	state_set[key] = sp = new_state(symbol);
21798e903e7SBaptiste Daroussin     }
21898e903e7SBaptiste Daroussin 
21998e903e7SBaptiste Daroussin     return (sp->number);
22098e903e7SBaptiste Daroussin }
22198e903e7SBaptiste Daroussin 
22298e903e7SBaptiste Daroussin static void
initialize_states(void)22398e903e7SBaptiste Daroussin initialize_states(void)
22498e903e7SBaptiste Daroussin {
22598e903e7SBaptiste Daroussin     unsigned i;
2260c8de5b0SBaptiste Daroussin     Value_t *start_derives;
22798e903e7SBaptiste Daroussin     core *p;
22898e903e7SBaptiste Daroussin 
22998e903e7SBaptiste Daroussin     start_derives = derives[start_symbol];
23098e903e7SBaptiste Daroussin     for (i = 0; start_derives[i] >= 0; ++i)
23198e903e7SBaptiste Daroussin 	continue;
23298e903e7SBaptiste Daroussin 
2330c8de5b0SBaptiste Daroussin     p = (core *)MALLOC(sizeof(core) + i * sizeof(Value_t));
23498e903e7SBaptiste Daroussin     NO_SPACE(p);
23598e903e7SBaptiste Daroussin 
23698e903e7SBaptiste Daroussin     p->next = 0;
23798e903e7SBaptiste Daroussin     p->link = 0;
23898e903e7SBaptiste Daroussin     p->number = 0;
23998e903e7SBaptiste Daroussin     p->accessing_symbol = 0;
24098e903e7SBaptiste Daroussin     p->nitems = (Value_t)i;
24198e903e7SBaptiste Daroussin 
24298e903e7SBaptiste Daroussin     for (i = 0; start_derives[i] >= 0; ++i)
24398e903e7SBaptiste Daroussin 	p->items[i] = rrhs[start_derives[i]];
24498e903e7SBaptiste Daroussin 
24598e903e7SBaptiste Daroussin     first_state = last_state = this_state = p;
24698e903e7SBaptiste Daroussin     nstates = 1;
24798e903e7SBaptiste Daroussin }
24898e903e7SBaptiste Daroussin 
24998e903e7SBaptiste Daroussin static void
new_itemsets(void)25098e903e7SBaptiste Daroussin new_itemsets(void)
25198e903e7SBaptiste Daroussin {
25298e903e7SBaptiste Daroussin     Value_t i;
25398e903e7SBaptiste Daroussin     int shiftcount;
2540c8de5b0SBaptiste Daroussin     Value_t *isp;
2550c8de5b0SBaptiste Daroussin     Value_t *ksp;
25698e903e7SBaptiste Daroussin 
25798e903e7SBaptiste Daroussin     for (i = 0; i < nsyms; i++)
25898e903e7SBaptiste Daroussin 	kernel_end[i] = 0;
25998e903e7SBaptiste Daroussin 
26098e903e7SBaptiste Daroussin     shiftcount = 0;
26198e903e7SBaptiste Daroussin     isp = itemset;
26298e903e7SBaptiste Daroussin     while (isp < itemsetend)
26398e903e7SBaptiste Daroussin     {
264*8e022d3cSDag-Erling Smørgrav 	int j = *isp++;
265*8e022d3cSDag-Erling Smørgrav 	Value_t symbol = ritem[j];
266*8e022d3cSDag-Erling Smørgrav 
26798e903e7SBaptiste Daroussin 	if (symbol > 0)
26898e903e7SBaptiste Daroussin 	{
26998e903e7SBaptiste Daroussin 	    ksp = kernel_end[symbol];
27098e903e7SBaptiste Daroussin 	    if (!ksp)
27198e903e7SBaptiste Daroussin 	    {
27298e903e7SBaptiste Daroussin 		shift_symbol[shiftcount++] = symbol;
27398e903e7SBaptiste Daroussin 		ksp = kernel_base[symbol];
27498e903e7SBaptiste Daroussin 	    }
27598e903e7SBaptiste Daroussin 
276*8e022d3cSDag-Erling Smørgrav 	    *ksp++ = (Value_t)(j + 1);
27798e903e7SBaptiste Daroussin 	    kernel_end[symbol] = ksp;
27898e903e7SBaptiste Daroussin 	}
27998e903e7SBaptiste Daroussin     }
28098e903e7SBaptiste Daroussin 
28198e903e7SBaptiste Daroussin     nshifts = shiftcount;
28298e903e7SBaptiste Daroussin }
28398e903e7SBaptiste Daroussin 
28498e903e7SBaptiste Daroussin static core *
new_state(int symbol)28598e903e7SBaptiste Daroussin new_state(int symbol)
28698e903e7SBaptiste Daroussin {
28798e903e7SBaptiste Daroussin     unsigned n;
28898e903e7SBaptiste Daroussin     core *p;
2890c8de5b0SBaptiste Daroussin     Value_t *isp1;
2900c8de5b0SBaptiste Daroussin     Value_t *isp2;
2910c8de5b0SBaptiste Daroussin     Value_t *iend;
29298e903e7SBaptiste Daroussin 
29398e903e7SBaptiste Daroussin #ifdef	TRACE
29498e903e7SBaptiste Daroussin     fprintf(stderr, "Entering new_state(%d)\n", symbol);
29598e903e7SBaptiste Daroussin #endif
29698e903e7SBaptiste Daroussin 
2970c8de5b0SBaptiste Daroussin     if (nstates >= MAXYYINT)
29898e903e7SBaptiste Daroussin 	fatal("too many states");
29998e903e7SBaptiste Daroussin 
30098e903e7SBaptiste Daroussin     isp1 = kernel_base[symbol];
30198e903e7SBaptiste Daroussin     iend = kernel_end[symbol];
30298e903e7SBaptiste Daroussin     n = (unsigned)(iend - isp1);
30398e903e7SBaptiste Daroussin 
3040c8de5b0SBaptiste Daroussin     p = (core *)allocate((sizeof(core) + (n - 1) * sizeof(Value_t)));
30598e903e7SBaptiste Daroussin     p->accessing_symbol = (Value_t)symbol;
30698e903e7SBaptiste Daroussin     p->number = (Value_t)nstates;
30798e903e7SBaptiste Daroussin     p->nitems = (Value_t)n;
30898e903e7SBaptiste Daroussin 
30998e903e7SBaptiste Daroussin     isp2 = p->items;
31098e903e7SBaptiste Daroussin     while (isp1 < iend)
31198e903e7SBaptiste Daroussin 	*isp2++ = *isp1++;
31298e903e7SBaptiste Daroussin 
31398e903e7SBaptiste Daroussin     last_state->next = p;
31498e903e7SBaptiste Daroussin     last_state = p;
31598e903e7SBaptiste Daroussin 
31698e903e7SBaptiste Daroussin     nstates++;
31798e903e7SBaptiste Daroussin 
31898e903e7SBaptiste Daroussin     return (p);
31998e903e7SBaptiste Daroussin }
32098e903e7SBaptiste Daroussin 
32198e903e7SBaptiste Daroussin /* show_cores is used for debugging */
3220c8de5b0SBaptiste Daroussin #ifdef DEBUG
32398e903e7SBaptiste Daroussin void
show_cores(void)32498e903e7SBaptiste Daroussin show_cores(void)
32598e903e7SBaptiste Daroussin {
32698e903e7SBaptiste Daroussin     core *p;
32798e903e7SBaptiste Daroussin     int i, j, k, n;
32898e903e7SBaptiste Daroussin     int itemno;
32998e903e7SBaptiste Daroussin 
33098e903e7SBaptiste Daroussin     k = 0;
33198e903e7SBaptiste Daroussin     for (p = first_state; p; ++k, p = p->next)
33298e903e7SBaptiste Daroussin     {
33398e903e7SBaptiste Daroussin 	if (k)
33498e903e7SBaptiste Daroussin 	    printf("\n");
33598e903e7SBaptiste Daroussin 	printf("state %d, number = %d, accessing symbol = %s\n",
33698e903e7SBaptiste Daroussin 	       k, p->number, symbol_name[p->accessing_symbol]);
33798e903e7SBaptiste Daroussin 	n = p->nitems;
33898e903e7SBaptiste Daroussin 	for (i = 0; i < n; ++i)
33998e903e7SBaptiste Daroussin 	{
34098e903e7SBaptiste Daroussin 	    itemno = p->items[i];
34198e903e7SBaptiste Daroussin 	    printf("%4d  ", itemno);
34298e903e7SBaptiste Daroussin 	    j = itemno;
34398e903e7SBaptiste Daroussin 	    while (ritem[j] >= 0)
34498e903e7SBaptiste Daroussin 		++j;
34598e903e7SBaptiste Daroussin 	    printf("%s :", symbol_name[rlhs[-ritem[j]]]);
34698e903e7SBaptiste Daroussin 	    j = rrhs[-ritem[j]];
34798e903e7SBaptiste Daroussin 	    while (j < itemno)
34898e903e7SBaptiste Daroussin 		printf(" %s", symbol_name[ritem[j++]]);
34998e903e7SBaptiste Daroussin 	    printf(" .");
35098e903e7SBaptiste Daroussin 	    while (ritem[j] >= 0)
35198e903e7SBaptiste Daroussin 		printf(" %s", symbol_name[ritem[j++]]);
35298e903e7SBaptiste Daroussin 	    printf("\n");
35398e903e7SBaptiste Daroussin 	    fflush(stdout);
35498e903e7SBaptiste Daroussin 	}
35598e903e7SBaptiste Daroussin     }
35698e903e7SBaptiste Daroussin }
35798e903e7SBaptiste Daroussin 
35898e903e7SBaptiste Daroussin /* show_ritems is used for debugging */
35998e903e7SBaptiste Daroussin 
36098e903e7SBaptiste Daroussin void
show_ritems(void)36198e903e7SBaptiste Daroussin show_ritems(void)
36298e903e7SBaptiste Daroussin {
36398e903e7SBaptiste Daroussin     int i;
36498e903e7SBaptiste Daroussin 
36598e903e7SBaptiste Daroussin     for (i = 0; i < nitems; ++i)
36698e903e7SBaptiste Daroussin 	printf("ritem[%d] = %d\n", i, ritem[i]);
36798e903e7SBaptiste Daroussin }
36898e903e7SBaptiste Daroussin 
36998e903e7SBaptiste Daroussin /* show_rrhs is used for debugging */
37098e903e7SBaptiste Daroussin void
show_rrhs(void)37198e903e7SBaptiste Daroussin show_rrhs(void)
37298e903e7SBaptiste Daroussin {
37398e903e7SBaptiste Daroussin     int i;
37498e903e7SBaptiste Daroussin 
37598e903e7SBaptiste Daroussin     for (i = 0; i < nrules; ++i)
37698e903e7SBaptiste Daroussin 	printf("rrhs[%d] = %d\n", i, rrhs[i]);
37798e903e7SBaptiste Daroussin }
37898e903e7SBaptiste Daroussin 
37998e903e7SBaptiste Daroussin /* show_shifts is used for debugging */
38098e903e7SBaptiste Daroussin 
38198e903e7SBaptiste Daroussin void
show_shifts(void)38298e903e7SBaptiste Daroussin show_shifts(void)
38398e903e7SBaptiste Daroussin {
38498e903e7SBaptiste Daroussin     shifts *p;
38598e903e7SBaptiste Daroussin     int i, j, k;
38698e903e7SBaptiste Daroussin 
38798e903e7SBaptiste Daroussin     k = 0;
38898e903e7SBaptiste Daroussin     for (p = first_shift; p; ++k, p = p->next)
38998e903e7SBaptiste Daroussin     {
39098e903e7SBaptiste Daroussin 	if (k)
39198e903e7SBaptiste Daroussin 	    printf("\n");
39298e903e7SBaptiste Daroussin 	printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
39398e903e7SBaptiste Daroussin 	       p->nshifts);
39498e903e7SBaptiste Daroussin 	j = p->nshifts;
39598e903e7SBaptiste Daroussin 	for (i = 0; i < j; ++i)
39698e903e7SBaptiste Daroussin 	    printf("\t%d\n", p->shift[i]);
39798e903e7SBaptiste Daroussin     }
39898e903e7SBaptiste Daroussin }
3990c8de5b0SBaptiste Daroussin #endif
40098e903e7SBaptiste Daroussin 
40198e903e7SBaptiste Daroussin static void
save_shifts(void)40298e903e7SBaptiste Daroussin save_shifts(void)
40398e903e7SBaptiste Daroussin {
40498e903e7SBaptiste Daroussin     shifts *p;
4050c8de5b0SBaptiste Daroussin     Value_t *sp1;
4060c8de5b0SBaptiste Daroussin     Value_t *sp2;
4070c8de5b0SBaptiste Daroussin     Value_t *send;
40898e903e7SBaptiste Daroussin 
40998e903e7SBaptiste Daroussin     p = (shifts *)allocate((sizeof(shifts) +
4100c8de5b0SBaptiste Daroussin 			      (unsigned)(nshifts - 1) * sizeof(Value_t)));
41198e903e7SBaptiste Daroussin 
41298e903e7SBaptiste Daroussin     p->number = this_state->number;
41398e903e7SBaptiste Daroussin     p->nshifts = (Value_t)nshifts;
41498e903e7SBaptiste Daroussin 
41598e903e7SBaptiste Daroussin     sp1 = shiftset;
41698e903e7SBaptiste Daroussin     sp2 = p->shift;
41798e903e7SBaptiste Daroussin     send = shiftset + nshifts;
41898e903e7SBaptiste Daroussin 
41998e903e7SBaptiste Daroussin     while (sp1 < send)
42098e903e7SBaptiste Daroussin 	*sp2++ = *sp1++;
42198e903e7SBaptiste Daroussin 
42298e903e7SBaptiste Daroussin     if (last_shift)
42398e903e7SBaptiste Daroussin     {
42498e903e7SBaptiste Daroussin 	last_shift->next = p;
42598e903e7SBaptiste Daroussin 	last_shift = p;
42698e903e7SBaptiste Daroussin     }
42798e903e7SBaptiste Daroussin     else
42898e903e7SBaptiste Daroussin     {
42998e903e7SBaptiste Daroussin 	first_shift = p;
43098e903e7SBaptiste Daroussin 	last_shift = p;
43198e903e7SBaptiste Daroussin     }
43298e903e7SBaptiste Daroussin }
43398e903e7SBaptiste Daroussin 
43498e903e7SBaptiste Daroussin static void
save_reductions(void)43598e903e7SBaptiste Daroussin save_reductions(void)
43698e903e7SBaptiste Daroussin {
4370c8de5b0SBaptiste Daroussin     Value_t *isp;
4380c8de5b0SBaptiste Daroussin     Value_t *rp1;
43998e903e7SBaptiste Daroussin     Value_t count;
44098e903e7SBaptiste Daroussin     reductions *p;
44198e903e7SBaptiste Daroussin 
44298e903e7SBaptiste Daroussin     count = 0;
44398e903e7SBaptiste Daroussin     for (isp = itemset; isp < itemsetend; isp++)
44498e903e7SBaptiste Daroussin     {
445*8e022d3cSDag-Erling Smørgrav 	int item = ritem[*isp];
446*8e022d3cSDag-Erling Smørgrav 
44798e903e7SBaptiste Daroussin 	if (item < 0)
44898e903e7SBaptiste Daroussin 	{
44998e903e7SBaptiste Daroussin 	    redset[count++] = (Value_t)-item;
45098e903e7SBaptiste Daroussin 	}
45198e903e7SBaptiste Daroussin     }
45298e903e7SBaptiste Daroussin 
45398e903e7SBaptiste Daroussin     if (count)
45498e903e7SBaptiste Daroussin     {
455*8e022d3cSDag-Erling Smørgrav 	Value_t *rp2;
456*8e022d3cSDag-Erling Smørgrav 	Value_t *rend;
457*8e022d3cSDag-Erling Smørgrav 
45898e903e7SBaptiste Daroussin 	p = (reductions *)allocate((sizeof(reductions) +
45998e903e7SBaptiste Daroussin 				      (unsigned)(count - 1) *
4600c8de5b0SBaptiste Daroussin 				    sizeof(Value_t)));
46198e903e7SBaptiste Daroussin 
46298e903e7SBaptiste Daroussin 	p->number = this_state->number;
46398e903e7SBaptiste Daroussin 	p->nreds = count;
46498e903e7SBaptiste Daroussin 
46598e903e7SBaptiste Daroussin 	rp1 = redset;
46698e903e7SBaptiste Daroussin 	rp2 = p->rules;
46798e903e7SBaptiste Daroussin 	rend = rp1 + count;
46898e903e7SBaptiste Daroussin 
46998e903e7SBaptiste Daroussin 	while (rp1 < rend)
47098e903e7SBaptiste Daroussin 	    *rp2++ = *rp1++;
47198e903e7SBaptiste Daroussin 
47298e903e7SBaptiste Daroussin 	if (last_reduction)
47398e903e7SBaptiste Daroussin 	{
47498e903e7SBaptiste Daroussin 	    last_reduction->next = p;
47598e903e7SBaptiste Daroussin 	    last_reduction = p;
47698e903e7SBaptiste Daroussin 	}
47798e903e7SBaptiste Daroussin 	else
47898e903e7SBaptiste Daroussin 	{
47998e903e7SBaptiste Daroussin 	    first_reduction = p;
48098e903e7SBaptiste Daroussin 	    last_reduction = p;
48198e903e7SBaptiste Daroussin 	}
48298e903e7SBaptiste Daroussin     }
48398e903e7SBaptiste Daroussin }
48498e903e7SBaptiste Daroussin 
48598e903e7SBaptiste Daroussin static void
set_derives(void)48698e903e7SBaptiste Daroussin set_derives(void)
48798e903e7SBaptiste Daroussin {
48898e903e7SBaptiste Daroussin     Value_t i, k;
48998e903e7SBaptiste Daroussin     int lhs;
49098e903e7SBaptiste Daroussin 
4910c8de5b0SBaptiste Daroussin     derives = NEW2(nsyms, Value_t *);
4920c8de5b0SBaptiste Daroussin     rules = NEW2(nvars + nrules, Value_t);
49398e903e7SBaptiste Daroussin 
49498e903e7SBaptiste Daroussin     k = 0;
49598e903e7SBaptiste Daroussin     for (lhs = start_symbol; lhs < nsyms; lhs++)
49698e903e7SBaptiste Daroussin     {
49798e903e7SBaptiste Daroussin 	derives[lhs] = rules + k;
49898e903e7SBaptiste Daroussin 	for (i = 0; i < nrules; i++)
49998e903e7SBaptiste Daroussin 	{
50098e903e7SBaptiste Daroussin 	    if (rlhs[i] == lhs)
50198e903e7SBaptiste Daroussin 	    {
50298e903e7SBaptiste Daroussin 		rules[k] = i;
50398e903e7SBaptiste Daroussin 		k++;
50498e903e7SBaptiste Daroussin 	    }
50598e903e7SBaptiste Daroussin 	}
50698e903e7SBaptiste Daroussin 	rules[k] = -1;
50798e903e7SBaptiste Daroussin 	k++;
50898e903e7SBaptiste Daroussin     }
50998e903e7SBaptiste Daroussin 
51098e903e7SBaptiste Daroussin #ifdef	DEBUG
51198e903e7SBaptiste Daroussin     print_derives();
51298e903e7SBaptiste Daroussin #endif
51398e903e7SBaptiste Daroussin }
51498e903e7SBaptiste Daroussin 
51598e903e7SBaptiste Daroussin #ifdef	DEBUG
51698e903e7SBaptiste Daroussin void
print_derives(void)51798e903e7SBaptiste Daroussin print_derives(void)
51898e903e7SBaptiste Daroussin {
51998e903e7SBaptiste Daroussin     int i;
5200c8de5b0SBaptiste Daroussin     Value_t *sp;
52198e903e7SBaptiste Daroussin 
52298e903e7SBaptiste Daroussin     printf("\nDERIVES\n\n");
52398e903e7SBaptiste Daroussin 
52498e903e7SBaptiste Daroussin     for (i = start_symbol; i < nsyms; i++)
52598e903e7SBaptiste Daroussin     {
52698e903e7SBaptiste Daroussin 	printf("%s derives ", symbol_name[i]);
52798e903e7SBaptiste Daroussin 	for (sp = derives[i]; *sp >= 0; sp++)
52898e903e7SBaptiste Daroussin 	{
52998e903e7SBaptiste Daroussin 	    printf("  %d", *sp);
53098e903e7SBaptiste Daroussin 	}
53198e903e7SBaptiste Daroussin 	putchar('\n');
53298e903e7SBaptiste Daroussin     }
53398e903e7SBaptiste Daroussin 
53498e903e7SBaptiste Daroussin     putchar('\n');
53598e903e7SBaptiste Daroussin }
53698e903e7SBaptiste Daroussin #endif
53798e903e7SBaptiste Daroussin 
53898e903e7SBaptiste Daroussin static void
set_nullable(void)53998e903e7SBaptiste Daroussin set_nullable(void)
54098e903e7SBaptiste Daroussin {
54198e903e7SBaptiste Daroussin     int i, j;
54298e903e7SBaptiste Daroussin     int empty;
54398e903e7SBaptiste Daroussin     int done_flag;
54498e903e7SBaptiste Daroussin 
5453e066022SBaptiste Daroussin     nullable = TMALLOC(char, nsyms);
54698e903e7SBaptiste Daroussin     NO_SPACE(nullable);
54798e903e7SBaptiste Daroussin 
54898e903e7SBaptiste Daroussin     for (i = 0; i < nsyms; ++i)
54998e903e7SBaptiste Daroussin 	nullable[i] = 0;
55098e903e7SBaptiste Daroussin 
55198e903e7SBaptiste Daroussin     done_flag = 0;
55298e903e7SBaptiste Daroussin     while (!done_flag)
55398e903e7SBaptiste Daroussin     {
55498e903e7SBaptiste Daroussin 	done_flag = 1;
55598e903e7SBaptiste Daroussin 	for (i = 1; i < nitems; i++)
55698e903e7SBaptiste Daroussin 	{
55798e903e7SBaptiste Daroussin 	    empty = 1;
55898e903e7SBaptiste Daroussin 	    while ((j = ritem[i]) >= 0)
55998e903e7SBaptiste Daroussin 	    {
56098e903e7SBaptiste Daroussin 		if (!nullable[j])
56198e903e7SBaptiste Daroussin 		    empty = 0;
56298e903e7SBaptiste Daroussin 		++i;
56398e903e7SBaptiste Daroussin 	    }
56498e903e7SBaptiste Daroussin 	    if (empty)
56598e903e7SBaptiste Daroussin 	    {
56698e903e7SBaptiste Daroussin 		j = rlhs[-j];
56798e903e7SBaptiste Daroussin 		if (!nullable[j])
56898e903e7SBaptiste Daroussin 		{
56998e903e7SBaptiste Daroussin 		    nullable[j] = 1;
57098e903e7SBaptiste Daroussin 		    done_flag = 0;
57198e903e7SBaptiste Daroussin 		}
57298e903e7SBaptiste Daroussin 	    }
57398e903e7SBaptiste Daroussin 	}
57498e903e7SBaptiste Daroussin     }
57598e903e7SBaptiste Daroussin 
57698e903e7SBaptiste Daroussin #ifdef DEBUG
57798e903e7SBaptiste Daroussin     for (i = 0; i < nsyms; i++)
57898e903e7SBaptiste Daroussin     {
57998e903e7SBaptiste Daroussin 	if (nullable[i])
58098e903e7SBaptiste Daroussin 	    printf("%s is nullable\n", symbol_name[i]);
58198e903e7SBaptiste Daroussin 	else
58298e903e7SBaptiste Daroussin 	    printf("%s is not nullable\n", symbol_name[i]);
58398e903e7SBaptiste Daroussin     }
58498e903e7SBaptiste Daroussin #endif
58598e903e7SBaptiste Daroussin }
58698e903e7SBaptiste Daroussin 
58798e903e7SBaptiste Daroussin void
lr0(void)58898e903e7SBaptiste Daroussin lr0(void)
58998e903e7SBaptiste Daroussin {
59098e903e7SBaptiste Daroussin     set_derives();
59198e903e7SBaptiste Daroussin     set_nullable();
59298e903e7SBaptiste Daroussin     generate_states();
59398e903e7SBaptiste Daroussin }
59498e903e7SBaptiste Daroussin 
59598e903e7SBaptiste Daroussin #ifdef NO_LEAKS
59698e903e7SBaptiste Daroussin void
lr0_leaks(void)59798e903e7SBaptiste Daroussin lr0_leaks(void)
59898e903e7SBaptiste Daroussin {
5990c8de5b0SBaptiste Daroussin     if (derives)
6000c8de5b0SBaptiste Daroussin     {
6010f86d14eSJung-uk Kim 	if (derives[start_symbol] != rules)
6020f86d14eSJung-uk Kim 	{
60398e903e7SBaptiste Daroussin 	    DO_FREE(derives[start_symbol]);
6040f86d14eSJung-uk Kim 	}
60598e903e7SBaptiste Daroussin 	DO_FREE(derives);
6060f86d14eSJung-uk Kim 	DO_FREE(rules);
6070c8de5b0SBaptiste Daroussin     }
60898e903e7SBaptiste Daroussin     DO_FREE(nullable);
60998e903e7SBaptiste Daroussin }
61098e903e7SBaptiste Daroussin #endif
611