xref: /freebsd/contrib/byacc/lr0.c (revision 0f86d14e9e2865f18166378c243bac94502953cf)
1*0f86d14eSJung-uk Kim /* $Id: lr0.c,v 1.18 2015/07/11 00:53:38 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 
1998e903e7SBaptiste Daroussin int 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 
33*0f86d14eSJung-uk Kim static Value_t *rules;
34*0f86d14eSJung-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
4398e903e7SBaptiste Daroussin allocate_itemsets(void)
4498e903e7SBaptiste Daroussin {
450c8de5b0SBaptiste Daroussin     Value_t *itemp;
460c8de5b0SBaptiste Daroussin     Value_t *item_end;
4798e903e7SBaptiste Daroussin     int symbol;
4898e903e7SBaptiste Daroussin     int i;
4998e903e7SBaptiste Daroussin     int count;
5098e903e7SBaptiste Daroussin     int max;
510c8de5b0SBaptiste Daroussin     Value_t *symbol_count;
5298e903e7SBaptiste Daroussin 
5398e903e7SBaptiste Daroussin     count = 0;
540c8de5b0SBaptiste Daroussin     symbol_count = NEW2(nsyms, Value_t);
5598e903e7SBaptiste Daroussin 
5698e903e7SBaptiste Daroussin     item_end = ritem + nitems;
5798e903e7SBaptiste Daroussin     for (itemp = ritem; itemp < item_end; itemp++)
5898e903e7SBaptiste Daroussin     {
5998e903e7SBaptiste Daroussin 	symbol = *itemp;
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
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
9498e903e7SBaptiste Daroussin append_states(void)
9598e903e7SBaptiste Daroussin {
9698e903e7SBaptiste Daroussin     int i;
9798e903e7SBaptiste Daroussin     int j;
9898e903e7SBaptiste Daroussin     Value_t symbol;
9998e903e7SBaptiste Daroussin 
10098e903e7SBaptiste Daroussin #ifdef	TRACE
10198e903e7SBaptiste Daroussin     fprintf(stderr, "Entering append_states()\n");
10298e903e7SBaptiste Daroussin #endif
10398e903e7SBaptiste Daroussin     for (i = 1; i < nshifts; i++)
10498e903e7SBaptiste Daroussin     {
10598e903e7SBaptiste Daroussin 	symbol = shift_symbol[i];
10698e903e7SBaptiste Daroussin 	j = 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
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
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
16098e903e7SBaptiste Daroussin get_state(int symbol)
16198e903e7SBaptiste Daroussin {
16298e903e7SBaptiste Daroussin     int key;
1630c8de5b0SBaptiste Daroussin     Value_t *isp1;
1640c8de5b0SBaptiste Daroussin     Value_t *isp2;
1650c8de5b0SBaptiste Daroussin     Value_t *iend;
16698e903e7SBaptiste Daroussin     core *sp;
16798e903e7SBaptiste Daroussin     int found;
16898e903e7SBaptiste Daroussin     int n;
16998e903e7SBaptiste Daroussin 
17098e903e7SBaptiste Daroussin #ifdef	TRACE
17198e903e7SBaptiste Daroussin     fprintf(stderr, "Entering get_state(%d)\n", symbol);
17298e903e7SBaptiste Daroussin #endif
17398e903e7SBaptiste Daroussin 
17498e903e7SBaptiste Daroussin     isp1 = kernel_base[symbol];
17598e903e7SBaptiste Daroussin     iend = kernel_end[symbol];
17698e903e7SBaptiste Daroussin     n = (int)(iend - isp1);
17798e903e7SBaptiste Daroussin 
17898e903e7SBaptiste Daroussin     key = *isp1;
17998e903e7SBaptiste Daroussin     assert(0 <= key && key < nitems);
18098e903e7SBaptiste Daroussin     sp = state_set[key];
18198e903e7SBaptiste Daroussin     if (sp)
18298e903e7SBaptiste Daroussin     {
18398e903e7SBaptiste Daroussin 	found = 0;
18498e903e7SBaptiste Daroussin 	while (!found)
18598e903e7SBaptiste Daroussin 	{
18698e903e7SBaptiste Daroussin 	    if (sp->nitems == n)
18798e903e7SBaptiste Daroussin 	    {
18898e903e7SBaptiste Daroussin 		found = 1;
18998e903e7SBaptiste Daroussin 		isp1 = kernel_base[symbol];
19098e903e7SBaptiste Daroussin 		isp2 = sp->items;
19198e903e7SBaptiste Daroussin 
19298e903e7SBaptiste Daroussin 		while (found && isp1 < iend)
19398e903e7SBaptiste Daroussin 		{
19498e903e7SBaptiste Daroussin 		    if (*isp1++ != *isp2++)
19598e903e7SBaptiste Daroussin 			found = 0;
19698e903e7SBaptiste Daroussin 		}
19798e903e7SBaptiste Daroussin 	    }
19898e903e7SBaptiste Daroussin 
19998e903e7SBaptiste Daroussin 	    if (!found)
20098e903e7SBaptiste Daroussin 	    {
20198e903e7SBaptiste Daroussin 		if (sp->link)
20298e903e7SBaptiste Daroussin 		{
20398e903e7SBaptiste Daroussin 		    sp = sp->link;
20498e903e7SBaptiste Daroussin 		}
20598e903e7SBaptiste Daroussin 		else
20698e903e7SBaptiste Daroussin 		{
20798e903e7SBaptiste Daroussin 		    sp = sp->link = new_state(symbol);
20898e903e7SBaptiste Daroussin 		    found = 1;
20998e903e7SBaptiste Daroussin 		}
21098e903e7SBaptiste Daroussin 	    }
21198e903e7SBaptiste Daroussin 	}
21298e903e7SBaptiste Daroussin     }
21398e903e7SBaptiste Daroussin     else
21498e903e7SBaptiste Daroussin     {
21598e903e7SBaptiste Daroussin 	state_set[key] = sp = new_state(symbol);
21698e903e7SBaptiste Daroussin     }
21798e903e7SBaptiste Daroussin 
21898e903e7SBaptiste Daroussin     return (sp->number);
21998e903e7SBaptiste Daroussin }
22098e903e7SBaptiste Daroussin 
22198e903e7SBaptiste Daroussin static void
22298e903e7SBaptiste Daroussin initialize_states(void)
22398e903e7SBaptiste Daroussin {
22498e903e7SBaptiste Daroussin     unsigned i;
2250c8de5b0SBaptiste Daroussin     Value_t *start_derives;
22698e903e7SBaptiste Daroussin     core *p;
22798e903e7SBaptiste Daroussin 
22898e903e7SBaptiste Daroussin     start_derives = derives[start_symbol];
22998e903e7SBaptiste Daroussin     for (i = 0; start_derives[i] >= 0; ++i)
23098e903e7SBaptiste Daroussin 	continue;
23198e903e7SBaptiste Daroussin 
2320c8de5b0SBaptiste Daroussin     p = (core *)MALLOC(sizeof(core) + i * sizeof(Value_t));
23398e903e7SBaptiste Daroussin     NO_SPACE(p);
23498e903e7SBaptiste Daroussin 
23598e903e7SBaptiste Daroussin     p->next = 0;
23698e903e7SBaptiste Daroussin     p->link = 0;
23798e903e7SBaptiste Daroussin     p->number = 0;
23898e903e7SBaptiste Daroussin     p->accessing_symbol = 0;
23998e903e7SBaptiste Daroussin     p->nitems = (Value_t) i;
24098e903e7SBaptiste Daroussin 
24198e903e7SBaptiste Daroussin     for (i = 0; start_derives[i] >= 0; ++i)
24298e903e7SBaptiste Daroussin 	p->items[i] = rrhs[start_derives[i]];
24398e903e7SBaptiste Daroussin 
24498e903e7SBaptiste Daroussin     first_state = last_state = this_state = p;
24598e903e7SBaptiste Daroussin     nstates = 1;
24698e903e7SBaptiste Daroussin }
24798e903e7SBaptiste Daroussin 
24898e903e7SBaptiste Daroussin static void
24998e903e7SBaptiste Daroussin new_itemsets(void)
25098e903e7SBaptiste Daroussin {
25198e903e7SBaptiste Daroussin     Value_t i;
25298e903e7SBaptiste Daroussin     int shiftcount;
2530c8de5b0SBaptiste Daroussin     Value_t *isp;
2540c8de5b0SBaptiste Daroussin     Value_t *ksp;
25598e903e7SBaptiste Daroussin     Value_t symbol;
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     {
26498e903e7SBaptiste Daroussin 	i = *isp++;
26598e903e7SBaptiste Daroussin 	symbol = ritem[i];
26698e903e7SBaptiste Daroussin 	if (symbol > 0)
26798e903e7SBaptiste Daroussin 	{
26898e903e7SBaptiste Daroussin 	    ksp = kernel_end[symbol];
26998e903e7SBaptiste Daroussin 	    if (!ksp)
27098e903e7SBaptiste Daroussin 	    {
27198e903e7SBaptiste Daroussin 		shift_symbol[shiftcount++] = symbol;
27298e903e7SBaptiste Daroussin 		ksp = kernel_base[symbol];
27398e903e7SBaptiste Daroussin 	    }
27498e903e7SBaptiste Daroussin 
27598e903e7SBaptiste Daroussin 	    *ksp++ = (Value_t) (i + 1);
27698e903e7SBaptiste Daroussin 	    kernel_end[symbol] = ksp;
27798e903e7SBaptiste Daroussin 	}
27898e903e7SBaptiste Daroussin     }
27998e903e7SBaptiste Daroussin 
28098e903e7SBaptiste Daroussin     nshifts = shiftcount;
28198e903e7SBaptiste Daroussin }
28298e903e7SBaptiste Daroussin 
28398e903e7SBaptiste Daroussin static core *
28498e903e7SBaptiste Daroussin new_state(int symbol)
28598e903e7SBaptiste Daroussin {
28698e903e7SBaptiste Daroussin     unsigned n;
28798e903e7SBaptiste Daroussin     core *p;
2880c8de5b0SBaptiste Daroussin     Value_t *isp1;
2890c8de5b0SBaptiste Daroussin     Value_t *isp2;
2900c8de5b0SBaptiste Daroussin     Value_t *iend;
29198e903e7SBaptiste Daroussin 
29298e903e7SBaptiste Daroussin #ifdef	TRACE
29398e903e7SBaptiste Daroussin     fprintf(stderr, "Entering new_state(%d)\n", symbol);
29498e903e7SBaptiste Daroussin #endif
29598e903e7SBaptiste Daroussin 
2960c8de5b0SBaptiste Daroussin     if (nstates >= MAXYYINT)
29798e903e7SBaptiste Daroussin 	fatal("too many states");
29898e903e7SBaptiste Daroussin 
29998e903e7SBaptiste Daroussin     isp1 = kernel_base[symbol];
30098e903e7SBaptiste Daroussin     iend = kernel_end[symbol];
30198e903e7SBaptiste Daroussin     n = (unsigned)(iend - isp1);
30298e903e7SBaptiste Daroussin 
3030c8de5b0SBaptiste Daroussin     p = (core *)allocate((sizeof(core) + (n - 1) * sizeof(Value_t)));
30498e903e7SBaptiste Daroussin     p->accessing_symbol = (Value_t) symbol;
30598e903e7SBaptiste Daroussin     p->number = (Value_t) nstates;
30698e903e7SBaptiste Daroussin     p->nitems = (Value_t) n;
30798e903e7SBaptiste Daroussin 
30898e903e7SBaptiste Daroussin     isp2 = p->items;
30998e903e7SBaptiste Daroussin     while (isp1 < iend)
31098e903e7SBaptiste Daroussin 	*isp2++ = *isp1++;
31198e903e7SBaptiste Daroussin 
31298e903e7SBaptiste Daroussin     last_state->next = p;
31398e903e7SBaptiste Daroussin     last_state = p;
31498e903e7SBaptiste Daroussin 
31598e903e7SBaptiste Daroussin     nstates++;
31698e903e7SBaptiste Daroussin 
31798e903e7SBaptiste Daroussin     return (p);
31898e903e7SBaptiste Daroussin }
31998e903e7SBaptiste Daroussin 
32098e903e7SBaptiste Daroussin /* show_cores is used for debugging */
3210c8de5b0SBaptiste Daroussin #ifdef DEBUG
32298e903e7SBaptiste Daroussin void
32398e903e7SBaptiste Daroussin show_cores(void)
32498e903e7SBaptiste Daroussin {
32598e903e7SBaptiste Daroussin     core *p;
32698e903e7SBaptiste Daroussin     int i, j, k, n;
32798e903e7SBaptiste Daroussin     int itemno;
32898e903e7SBaptiste Daroussin 
32998e903e7SBaptiste Daroussin     k = 0;
33098e903e7SBaptiste Daroussin     for (p = first_state; p; ++k, p = p->next)
33198e903e7SBaptiste Daroussin     {
33298e903e7SBaptiste Daroussin 	if (k)
33398e903e7SBaptiste Daroussin 	    printf("\n");
33498e903e7SBaptiste Daroussin 	printf("state %d, number = %d, accessing symbol = %s\n",
33598e903e7SBaptiste Daroussin 	       k, p->number, symbol_name[p->accessing_symbol]);
33698e903e7SBaptiste Daroussin 	n = p->nitems;
33798e903e7SBaptiste Daroussin 	for (i = 0; i < n; ++i)
33898e903e7SBaptiste Daroussin 	{
33998e903e7SBaptiste Daroussin 	    itemno = p->items[i];
34098e903e7SBaptiste Daroussin 	    printf("%4d  ", itemno);
34198e903e7SBaptiste Daroussin 	    j = itemno;
34298e903e7SBaptiste Daroussin 	    while (ritem[j] >= 0)
34398e903e7SBaptiste Daroussin 		++j;
34498e903e7SBaptiste Daroussin 	    printf("%s :", symbol_name[rlhs[-ritem[j]]]);
34598e903e7SBaptiste Daroussin 	    j = rrhs[-ritem[j]];
34698e903e7SBaptiste Daroussin 	    while (j < itemno)
34798e903e7SBaptiste Daroussin 		printf(" %s", symbol_name[ritem[j++]]);
34898e903e7SBaptiste Daroussin 	    printf(" .");
34998e903e7SBaptiste Daroussin 	    while (ritem[j] >= 0)
35098e903e7SBaptiste Daroussin 		printf(" %s", symbol_name[ritem[j++]]);
35198e903e7SBaptiste Daroussin 	    printf("\n");
35298e903e7SBaptiste Daroussin 	    fflush(stdout);
35398e903e7SBaptiste Daroussin 	}
35498e903e7SBaptiste Daroussin     }
35598e903e7SBaptiste Daroussin }
35698e903e7SBaptiste Daroussin 
35798e903e7SBaptiste Daroussin /* show_ritems is used for debugging */
35898e903e7SBaptiste Daroussin 
35998e903e7SBaptiste Daroussin void
36098e903e7SBaptiste Daroussin show_ritems(void)
36198e903e7SBaptiste Daroussin {
36298e903e7SBaptiste Daroussin     int i;
36398e903e7SBaptiste Daroussin 
36498e903e7SBaptiste Daroussin     for (i = 0; i < nitems; ++i)
36598e903e7SBaptiste Daroussin 	printf("ritem[%d] = %d\n", i, ritem[i]);
36698e903e7SBaptiste Daroussin }
36798e903e7SBaptiste Daroussin 
36898e903e7SBaptiste Daroussin /* show_rrhs is used for debugging */
36998e903e7SBaptiste Daroussin void
37098e903e7SBaptiste Daroussin show_rrhs(void)
37198e903e7SBaptiste Daroussin {
37298e903e7SBaptiste Daroussin     int i;
37398e903e7SBaptiste Daroussin 
37498e903e7SBaptiste Daroussin     for (i = 0; i < nrules; ++i)
37598e903e7SBaptiste Daroussin 	printf("rrhs[%d] = %d\n", i, rrhs[i]);
37698e903e7SBaptiste Daroussin }
37798e903e7SBaptiste Daroussin 
37898e903e7SBaptiste Daroussin /* show_shifts is used for debugging */
37998e903e7SBaptiste Daroussin 
38098e903e7SBaptiste Daroussin void
38198e903e7SBaptiste Daroussin show_shifts(void)
38298e903e7SBaptiste Daroussin {
38398e903e7SBaptiste Daroussin     shifts *p;
38498e903e7SBaptiste Daroussin     int i, j, k;
38598e903e7SBaptiste Daroussin 
38698e903e7SBaptiste Daroussin     k = 0;
38798e903e7SBaptiste Daroussin     for (p = first_shift; p; ++k, p = p->next)
38898e903e7SBaptiste Daroussin     {
38998e903e7SBaptiste Daroussin 	if (k)
39098e903e7SBaptiste Daroussin 	    printf("\n");
39198e903e7SBaptiste Daroussin 	printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
39298e903e7SBaptiste Daroussin 	       p->nshifts);
39398e903e7SBaptiste Daroussin 	j = p->nshifts;
39498e903e7SBaptiste Daroussin 	for (i = 0; i < j; ++i)
39598e903e7SBaptiste Daroussin 	    printf("\t%d\n", p->shift[i]);
39698e903e7SBaptiste Daroussin     }
39798e903e7SBaptiste Daroussin }
3980c8de5b0SBaptiste Daroussin #endif
39998e903e7SBaptiste Daroussin 
40098e903e7SBaptiste Daroussin static void
40198e903e7SBaptiste Daroussin save_shifts(void)
40298e903e7SBaptiste Daroussin {
40398e903e7SBaptiste Daroussin     shifts *p;
4040c8de5b0SBaptiste Daroussin     Value_t *sp1;
4050c8de5b0SBaptiste Daroussin     Value_t *sp2;
4060c8de5b0SBaptiste Daroussin     Value_t *send;
40798e903e7SBaptiste Daroussin 
40898e903e7SBaptiste Daroussin     p = (shifts *)allocate((sizeof(shifts) +
4090c8de5b0SBaptiste Daroussin 			      (unsigned)(nshifts - 1) * sizeof(Value_t)));
41098e903e7SBaptiste Daroussin 
41198e903e7SBaptiste Daroussin     p->number = this_state->number;
41298e903e7SBaptiste Daroussin     p->nshifts = (Value_t) nshifts;
41398e903e7SBaptiste Daroussin 
41498e903e7SBaptiste Daroussin     sp1 = shiftset;
41598e903e7SBaptiste Daroussin     sp2 = p->shift;
41698e903e7SBaptiste Daroussin     send = shiftset + nshifts;
41798e903e7SBaptiste Daroussin 
41898e903e7SBaptiste Daroussin     while (sp1 < send)
41998e903e7SBaptiste Daroussin 	*sp2++ = *sp1++;
42098e903e7SBaptiste Daroussin 
42198e903e7SBaptiste Daroussin     if (last_shift)
42298e903e7SBaptiste Daroussin     {
42398e903e7SBaptiste Daroussin 	last_shift->next = p;
42498e903e7SBaptiste Daroussin 	last_shift = p;
42598e903e7SBaptiste Daroussin     }
42698e903e7SBaptiste Daroussin     else
42798e903e7SBaptiste Daroussin     {
42898e903e7SBaptiste Daroussin 	first_shift = p;
42998e903e7SBaptiste Daroussin 	last_shift = p;
43098e903e7SBaptiste Daroussin     }
43198e903e7SBaptiste Daroussin }
43298e903e7SBaptiste Daroussin 
43398e903e7SBaptiste Daroussin static void
43498e903e7SBaptiste Daroussin save_reductions(void)
43598e903e7SBaptiste Daroussin {
4360c8de5b0SBaptiste Daroussin     Value_t *isp;
4370c8de5b0SBaptiste Daroussin     Value_t *rp1;
4380c8de5b0SBaptiste Daroussin     Value_t *rp2;
43998e903e7SBaptiste Daroussin     int item;
44098e903e7SBaptiste Daroussin     Value_t count;
44198e903e7SBaptiste Daroussin     reductions *p;
4420c8de5b0SBaptiste Daroussin     Value_t *rend;
44398e903e7SBaptiste Daroussin 
44498e903e7SBaptiste Daroussin     count = 0;
44598e903e7SBaptiste Daroussin     for (isp = itemset; isp < itemsetend; isp++)
44698e903e7SBaptiste Daroussin     {
44798e903e7SBaptiste Daroussin 	item = ritem[*isp];
44898e903e7SBaptiste Daroussin 	if (item < 0)
44998e903e7SBaptiste Daroussin 	{
45098e903e7SBaptiste Daroussin 	    redset[count++] = (Value_t) - item;
45198e903e7SBaptiste Daroussin 	}
45298e903e7SBaptiste Daroussin     }
45398e903e7SBaptiste Daroussin 
45498e903e7SBaptiste Daroussin     if (count)
45598e903e7SBaptiste Daroussin     {
45698e903e7SBaptiste Daroussin 	p = (reductions *)allocate((sizeof(reductions) +
45798e903e7SBaptiste Daroussin 				      (unsigned)(count - 1) *
4580c8de5b0SBaptiste Daroussin 				    sizeof(Value_t)));
45998e903e7SBaptiste Daroussin 
46098e903e7SBaptiste Daroussin 	p->number = this_state->number;
46198e903e7SBaptiste Daroussin 	p->nreds = count;
46298e903e7SBaptiste Daroussin 
46398e903e7SBaptiste Daroussin 	rp1 = redset;
46498e903e7SBaptiste Daroussin 	rp2 = p->rules;
46598e903e7SBaptiste Daroussin 	rend = rp1 + count;
46698e903e7SBaptiste Daroussin 
46798e903e7SBaptiste Daroussin 	while (rp1 < rend)
46898e903e7SBaptiste Daroussin 	    *rp2++ = *rp1++;
46998e903e7SBaptiste Daroussin 
47098e903e7SBaptiste Daroussin 	if (last_reduction)
47198e903e7SBaptiste Daroussin 	{
47298e903e7SBaptiste Daroussin 	    last_reduction->next = p;
47398e903e7SBaptiste Daroussin 	    last_reduction = p;
47498e903e7SBaptiste Daroussin 	}
47598e903e7SBaptiste Daroussin 	else
47698e903e7SBaptiste Daroussin 	{
47798e903e7SBaptiste Daroussin 	    first_reduction = p;
47898e903e7SBaptiste Daroussin 	    last_reduction = p;
47998e903e7SBaptiste Daroussin 	}
48098e903e7SBaptiste Daroussin     }
48198e903e7SBaptiste Daroussin }
48298e903e7SBaptiste Daroussin 
48398e903e7SBaptiste Daroussin static void
48498e903e7SBaptiste Daroussin set_derives(void)
48598e903e7SBaptiste Daroussin {
48698e903e7SBaptiste Daroussin     Value_t i, k;
48798e903e7SBaptiste Daroussin     int lhs;
48898e903e7SBaptiste Daroussin 
4890c8de5b0SBaptiste Daroussin     derives = NEW2(nsyms, Value_t *);
4900c8de5b0SBaptiste Daroussin     rules = NEW2(nvars + nrules, Value_t);
49198e903e7SBaptiste Daroussin 
49298e903e7SBaptiste Daroussin     k = 0;
49398e903e7SBaptiste Daroussin     for (lhs = start_symbol; lhs < nsyms; lhs++)
49498e903e7SBaptiste Daroussin     {
49598e903e7SBaptiste Daroussin 	derives[lhs] = rules + k;
49698e903e7SBaptiste Daroussin 	for (i = 0; i < nrules; i++)
49798e903e7SBaptiste Daroussin 	{
49898e903e7SBaptiste Daroussin 	    if (rlhs[i] == lhs)
49998e903e7SBaptiste Daroussin 	    {
50098e903e7SBaptiste Daroussin 		rules[k] = i;
50198e903e7SBaptiste Daroussin 		k++;
50298e903e7SBaptiste Daroussin 	    }
50398e903e7SBaptiste Daroussin 	}
50498e903e7SBaptiste Daroussin 	rules[k] = -1;
50598e903e7SBaptiste Daroussin 	k++;
50698e903e7SBaptiste Daroussin     }
50798e903e7SBaptiste Daroussin 
50898e903e7SBaptiste Daroussin #ifdef	DEBUG
50998e903e7SBaptiste Daroussin     print_derives();
51098e903e7SBaptiste Daroussin #endif
51198e903e7SBaptiste Daroussin }
51298e903e7SBaptiste Daroussin 
51398e903e7SBaptiste Daroussin #ifdef	DEBUG
51498e903e7SBaptiste Daroussin void
51598e903e7SBaptiste Daroussin print_derives(void)
51698e903e7SBaptiste Daroussin {
51798e903e7SBaptiste Daroussin     int i;
5180c8de5b0SBaptiste Daroussin     Value_t *sp;
51998e903e7SBaptiste Daroussin 
52098e903e7SBaptiste Daroussin     printf("\nDERIVES\n\n");
52198e903e7SBaptiste Daroussin 
52298e903e7SBaptiste Daroussin     for (i = start_symbol; i < nsyms; i++)
52398e903e7SBaptiste Daroussin     {
52498e903e7SBaptiste Daroussin 	printf("%s derives ", symbol_name[i]);
52598e903e7SBaptiste Daroussin 	for (sp = derives[i]; *sp >= 0; sp++)
52698e903e7SBaptiste Daroussin 	{
52798e903e7SBaptiste Daroussin 	    printf("  %d", *sp);
52898e903e7SBaptiste Daroussin 	}
52998e903e7SBaptiste Daroussin 	putchar('\n');
53098e903e7SBaptiste Daroussin     }
53198e903e7SBaptiste Daroussin 
53298e903e7SBaptiste Daroussin     putchar('\n');
53398e903e7SBaptiste Daroussin }
53498e903e7SBaptiste Daroussin #endif
53598e903e7SBaptiste Daroussin 
53698e903e7SBaptiste Daroussin static void
53798e903e7SBaptiste Daroussin set_nullable(void)
53898e903e7SBaptiste Daroussin {
53998e903e7SBaptiste Daroussin     int i, j;
54098e903e7SBaptiste Daroussin     int empty;
54198e903e7SBaptiste Daroussin     int done_flag;
54298e903e7SBaptiste Daroussin 
5433e066022SBaptiste Daroussin     nullable = TMALLOC(char, nsyms);
54498e903e7SBaptiste Daroussin     NO_SPACE(nullable);
54598e903e7SBaptiste Daroussin 
54698e903e7SBaptiste Daroussin     for (i = 0; i < nsyms; ++i)
54798e903e7SBaptiste Daroussin 	nullable[i] = 0;
54898e903e7SBaptiste Daroussin 
54998e903e7SBaptiste Daroussin     done_flag = 0;
55098e903e7SBaptiste Daroussin     while (!done_flag)
55198e903e7SBaptiste Daroussin     {
55298e903e7SBaptiste Daroussin 	done_flag = 1;
55398e903e7SBaptiste Daroussin 	for (i = 1; i < nitems; i++)
55498e903e7SBaptiste Daroussin 	{
55598e903e7SBaptiste Daroussin 	    empty = 1;
55698e903e7SBaptiste Daroussin 	    while ((j = ritem[i]) >= 0)
55798e903e7SBaptiste Daroussin 	    {
55898e903e7SBaptiste Daroussin 		if (!nullable[j])
55998e903e7SBaptiste Daroussin 		    empty = 0;
56098e903e7SBaptiste Daroussin 		++i;
56198e903e7SBaptiste Daroussin 	    }
56298e903e7SBaptiste Daroussin 	    if (empty)
56398e903e7SBaptiste Daroussin 	    {
56498e903e7SBaptiste Daroussin 		j = rlhs[-j];
56598e903e7SBaptiste Daroussin 		if (!nullable[j])
56698e903e7SBaptiste Daroussin 		{
56798e903e7SBaptiste Daroussin 		    nullable[j] = 1;
56898e903e7SBaptiste Daroussin 		    done_flag = 0;
56998e903e7SBaptiste Daroussin 		}
57098e903e7SBaptiste Daroussin 	    }
57198e903e7SBaptiste Daroussin 	}
57298e903e7SBaptiste Daroussin     }
57398e903e7SBaptiste Daroussin 
57498e903e7SBaptiste Daroussin #ifdef DEBUG
57598e903e7SBaptiste Daroussin     for (i = 0; i < nsyms; i++)
57698e903e7SBaptiste Daroussin     {
57798e903e7SBaptiste Daroussin 	if (nullable[i])
57898e903e7SBaptiste Daroussin 	    printf("%s is nullable\n", symbol_name[i]);
57998e903e7SBaptiste Daroussin 	else
58098e903e7SBaptiste Daroussin 	    printf("%s is not nullable\n", symbol_name[i]);
58198e903e7SBaptiste Daroussin     }
58298e903e7SBaptiste Daroussin #endif
58398e903e7SBaptiste Daroussin }
58498e903e7SBaptiste Daroussin 
58598e903e7SBaptiste Daroussin void
58698e903e7SBaptiste Daroussin lr0(void)
58798e903e7SBaptiste Daroussin {
58898e903e7SBaptiste Daroussin     set_derives();
58998e903e7SBaptiste Daroussin     set_nullable();
59098e903e7SBaptiste Daroussin     generate_states();
59198e903e7SBaptiste Daroussin }
59298e903e7SBaptiste Daroussin 
59398e903e7SBaptiste Daroussin #ifdef NO_LEAKS
59498e903e7SBaptiste Daroussin void
59598e903e7SBaptiste Daroussin lr0_leaks(void)
59698e903e7SBaptiste Daroussin {
5970c8de5b0SBaptiste Daroussin     if (derives)
5980c8de5b0SBaptiste Daroussin     {
599*0f86d14eSJung-uk Kim 	if (derives[start_symbol] != rules)
600*0f86d14eSJung-uk Kim 	{
60198e903e7SBaptiste Daroussin 	    DO_FREE(derives[start_symbol]);
602*0f86d14eSJung-uk Kim 	}
60398e903e7SBaptiste Daroussin 	DO_FREE(derives);
604*0f86d14eSJung-uk Kim 	DO_FREE(rules);
6050c8de5b0SBaptiste Daroussin     }
60698e903e7SBaptiste Daroussin     DO_FREE(nullable);
60798e903e7SBaptiste Daroussin }
60898e903e7SBaptiste Daroussin #endif
609