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