139777Sbostic /*
239777Sbostic * Copyright (c) 1989 The Regents of the University of California.
339777Sbostic * All rights reserved.
439777Sbostic *
539777Sbostic * This code is derived from software contributed to Berkeley by
639777Sbostic * Robert Paul Corbett.
739777Sbostic *
842698Sbostic * %sccs.include.redist.c%
939777Sbostic */
1039777Sbostic
1139777Sbostic #ifndef lint
12*46061Scorbett static char sccsid[] = "@(#)lr0.c 5.3 (Berkeley) 01/20/91";
1339777Sbostic #endif /* not lint */
1439777Sbostic
1539777Sbostic #include "defs.h"
1639777Sbostic
1739777Sbostic extern short *itemset;
1839777Sbostic extern short *itemsetend;
1939777Sbostic extern unsigned *ruleset;
2039777Sbostic
2139777Sbostic int nstates;
2239777Sbostic core *first_state;
2339777Sbostic shifts *first_shift;
2439777Sbostic reductions *first_reduction;
2539777Sbostic
2639777Sbostic int get_state();
2739777Sbostic core *new_state();
2839777Sbostic
29*46061Scorbett static core **state_set;
3039777Sbostic static core *this_state;
3139777Sbostic static core *last_state;
3239777Sbostic static shifts *last_shift;
3339777Sbostic static reductions *last_reduction;
3439777Sbostic
3539777Sbostic static int nshifts;
3639777Sbostic static short *shift_symbol;
3739777Sbostic
3839777Sbostic static short *redset;
3939777Sbostic static short *shiftset;
4039777Sbostic
4139777Sbostic static short **kernel_base;
4239777Sbostic static short **kernel_end;
4339777Sbostic static short *kernel_items;
4439777Sbostic
4539777Sbostic
allocate_itemsets()4639777Sbostic allocate_itemsets()
4739777Sbostic {
48*46061Scorbett register short *itemp;
49*46061Scorbett register short *item_end;
50*46061Scorbett register int symbol;
51*46061Scorbett register int i;
52*46061Scorbett register int count;
53*46061Scorbett register int max;
54*46061Scorbett register short *symbol_count;
5539777Sbostic
56*46061Scorbett count = 0;
57*46061Scorbett symbol_count = NEW2(nsyms, short);
5839777Sbostic
59*46061Scorbett item_end = ritem + nitems;
60*46061Scorbett for (itemp = ritem; itemp < item_end; itemp++)
6139777Sbostic {
62*46061Scorbett symbol = *itemp;
63*46061Scorbett if (symbol >= 0)
6439777Sbostic {
65*46061Scorbett count++;
66*46061Scorbett symbol_count[symbol]++;
6739777Sbostic }
6839777Sbostic }
6939777Sbostic
70*46061Scorbett kernel_base = NEW2(nsyms, short *);
71*46061Scorbett kernel_items = NEW2(count, short);
7239777Sbostic
73*46061Scorbett count = 0;
74*46061Scorbett max = 0;
75*46061Scorbett for (i = 0; i < nsyms; i++)
7639777Sbostic {
77*46061Scorbett kernel_base[i] = kernel_items + count;
78*46061Scorbett count += symbol_count[i];
79*46061Scorbett if (max < symbol_count[i])
80*46061Scorbett max = symbol_count[i];
8139777Sbostic }
8239777Sbostic
83*46061Scorbett shift_symbol = symbol_count;
84*46061Scorbett kernel_end = NEW2(nsyms, short *);
8539777Sbostic }
8639777Sbostic
8739777Sbostic
allocate_storage()8839777Sbostic allocate_storage()
8939777Sbostic {
90*46061Scorbett allocate_itemsets();
91*46061Scorbett shiftset = NEW2(nsyms, short);
92*46061Scorbett redset = NEW2(nrules + 1, short);
93*46061Scorbett state_set = NEW2(nitems, core *);
9439777Sbostic }
9539777Sbostic
9639777Sbostic
append_states()9739777Sbostic append_states()
9839777Sbostic {
99*46061Scorbett register int i;
100*46061Scorbett register int j;
101*46061Scorbett register int symbol;
10239777Sbostic
10339777Sbostic #ifdef TRACE
104*46061Scorbett fprintf(stderr, "Entering append_states()\n");
10539777Sbostic #endif
106*46061Scorbett for (i = 1; i < nshifts; i++)
10739777Sbostic {
108*46061Scorbett symbol = shift_symbol[i];
109*46061Scorbett j = i;
110*46061Scorbett while (j > 0 && shift_symbol[j - 1] > symbol)
11139777Sbostic {
112*46061Scorbett shift_symbol[j] = shift_symbol[j - 1];
113*46061Scorbett j--;
11439777Sbostic }
115*46061Scorbett shift_symbol[j] = symbol;
11639777Sbostic }
11739777Sbostic
118*46061Scorbett for (i = 0; i < nshifts; i++)
11939777Sbostic {
120*46061Scorbett symbol = shift_symbol[i];
121*46061Scorbett shiftset[i] = get_state(symbol);
12239777Sbostic }
12339777Sbostic }
12439777Sbostic
12539777Sbostic
free_storage()12639777Sbostic free_storage()
12739777Sbostic {
128*46061Scorbett FREE(shift_symbol);
129*46061Scorbett FREE(redset);
130*46061Scorbett FREE(shiftset);
131*46061Scorbett FREE(kernel_base);
132*46061Scorbett FREE(kernel_end);
133*46061Scorbett FREE(kernel_items);
134*46061Scorbett FREE(state_set);
13539777Sbostic }
13639777Sbostic
13739777Sbostic
13839777Sbostic
generate_states()13939777Sbostic generate_states()
14039777Sbostic {
141*46061Scorbett allocate_storage();
142*46061Scorbett itemset = NEW2(nitems, short);
143*46061Scorbett ruleset = NEW2(WORDSIZE(nrules), unsigned);
144*46061Scorbett set_first_derives();
145*46061Scorbett initialize_states();
14639777Sbostic
147*46061Scorbett while (this_state)
14839777Sbostic {
149*46061Scorbett closure(this_state->items, this_state->nitems);
150*46061Scorbett save_reductions();
151*46061Scorbett new_itemsets();
152*46061Scorbett append_states();
15339777Sbostic
154*46061Scorbett if (nshifts > 0)
155*46061Scorbett save_shifts();
15639777Sbostic
157*46061Scorbett this_state = this_state->next;
15839777Sbostic }
15939777Sbostic
160*46061Scorbett finalize_closure();
161*46061Scorbett free_storage();
16239777Sbostic }
16339777Sbostic
16439777Sbostic
16539777Sbostic
16639777Sbostic int
get_state(symbol)16739777Sbostic get_state(symbol)
16839777Sbostic int symbol;
16939777Sbostic {
170*46061Scorbett register int key;
171*46061Scorbett register short *isp1;
172*46061Scorbett register short *isp2;
173*46061Scorbett register short *iend;
174*46061Scorbett register core *sp;
175*46061Scorbett register int found;
176*46061Scorbett register int n;
17739777Sbostic
17839777Sbostic #ifdef TRACE
179*46061Scorbett fprintf(stderr, "Entering get_state(%d)\n", symbol);
18039777Sbostic #endif
18139777Sbostic
182*46061Scorbett isp1 = kernel_base[symbol];
183*46061Scorbett iend = kernel_end[symbol];
184*46061Scorbett n = iend - isp1;
18539777Sbostic
186*46061Scorbett key = *isp1;
187*46061Scorbett assert(0 <= key && key < nitems);
188*46061Scorbett sp = state_set[key];
189*46061Scorbett if (sp)
19039777Sbostic {
191*46061Scorbett found = 0;
192*46061Scorbett while (!found)
19339777Sbostic {
194*46061Scorbett if (sp->nitems == n)
19539777Sbostic {
196*46061Scorbett found = 1;
197*46061Scorbett isp1 = kernel_base[symbol];
198*46061Scorbett isp2 = sp->items;
19939777Sbostic
200*46061Scorbett while (found && isp1 < iend)
20139777Sbostic {
202*46061Scorbett if (*isp1++ != *isp2++)
203*46061Scorbett found = 0;
20439777Sbostic }
20539777Sbostic }
20639777Sbostic
207*46061Scorbett if (!found)
20839777Sbostic {
209*46061Scorbett if (sp->link)
21039777Sbostic {
211*46061Scorbett sp = sp->link;
21239777Sbostic }
213*46061Scorbett else
21439777Sbostic {
215*46061Scorbett sp = sp->link = new_state(symbol);
216*46061Scorbett found = 1;
21739777Sbostic }
21839777Sbostic }
21939777Sbostic }
22039777Sbostic }
221*46061Scorbett else
22239777Sbostic {
223*46061Scorbett state_set[key] = sp = new_state(symbol);
22439777Sbostic }
22539777Sbostic
226*46061Scorbett return (sp->number);
22739777Sbostic }
22839777Sbostic
22939777Sbostic
23039777Sbostic
initialize_states()23139777Sbostic initialize_states()
23239777Sbostic {
23339777Sbostic register int i;
23439777Sbostic register short *start_derives;
23539777Sbostic register core *p;
23639777Sbostic
23739777Sbostic start_derives = derives[start_symbol];
23839777Sbostic for (i = 0; start_derives[i] >= 0; ++i)
23939777Sbostic continue;
24039777Sbostic
24139777Sbostic p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
24239777Sbostic if (p == 0) no_space();
24339777Sbostic
24439777Sbostic p->next = 0;
24539777Sbostic p->link = 0;
24639777Sbostic p->number = 0;
24739777Sbostic p->accessing_symbol = 0;
24839777Sbostic p->nitems = i;
24939777Sbostic
25039777Sbostic for (i = 0; start_derives[i] >= 0; ++i)
25139777Sbostic p->items[i] = rrhs[start_derives[i]];
25239777Sbostic
25339777Sbostic first_state = last_state = this_state = p;
25439777Sbostic nstates = 1;
25539777Sbostic }
25639777Sbostic
25739777Sbostic
new_itemsets()25839777Sbostic new_itemsets()
25939777Sbostic {
260*46061Scorbett register int i;
261*46061Scorbett register int shiftcount;
262*46061Scorbett register short *isp;
263*46061Scorbett register short *ksp;
264*46061Scorbett register int symbol;
26539777Sbostic
266*46061Scorbett for (i = 0; i < nsyms; i++)
267*46061Scorbett kernel_end[i] = 0;
26839777Sbostic
269*46061Scorbett shiftcount = 0;
270*46061Scorbett isp = itemset;
271*46061Scorbett while (isp < itemsetend)
27239777Sbostic {
273*46061Scorbett i = *isp++;
274*46061Scorbett symbol = ritem[i];
275*46061Scorbett if (symbol > 0)
27639777Sbostic {
277*46061Scorbett ksp = kernel_end[symbol];
278*46061Scorbett if (!ksp)
27939777Sbostic {
280*46061Scorbett shift_symbol[shiftcount++] = symbol;
281*46061Scorbett ksp = kernel_base[symbol];
28239777Sbostic }
28339777Sbostic
284*46061Scorbett *ksp++ = i + 1;
285*46061Scorbett kernel_end[symbol] = ksp;
28639777Sbostic }
28739777Sbostic }
28839777Sbostic
289*46061Scorbett nshifts = shiftcount;
29039777Sbostic }
29139777Sbostic
29239777Sbostic
29339777Sbostic
29439777Sbostic core *
new_state(symbol)29539777Sbostic new_state(symbol)
29639777Sbostic int symbol;
29739777Sbostic {
298*46061Scorbett register int n;
299*46061Scorbett register core *p;
300*46061Scorbett register short *isp1;
301*46061Scorbett register short *isp2;
302*46061Scorbett register short *iend;
30339777Sbostic
30439777Sbostic #ifdef TRACE
305*46061Scorbett fprintf(stderr, "Entering new_state(%d)\n", symbol);
30639777Sbostic #endif
30739777Sbostic
308*46061Scorbett if (nstates >= MAXSHORT)
309*46061Scorbett fatal("too many states");
31039777Sbostic
311*46061Scorbett isp1 = kernel_base[symbol];
312*46061Scorbett iend = kernel_end[symbol];
313*46061Scorbett n = iend - isp1;
31439777Sbostic
315*46061Scorbett p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
316*46061Scorbett p->accessing_symbol = symbol;
317*46061Scorbett p->number = nstates;
318*46061Scorbett p->nitems = n;
31939777Sbostic
320*46061Scorbett isp2 = p->items;
321*46061Scorbett while (isp1 < iend)
322*46061Scorbett *isp2++ = *isp1++;
32339777Sbostic
324*46061Scorbett last_state->next = p;
325*46061Scorbett last_state = p;
32639777Sbostic
327*46061Scorbett nstates++;
32839777Sbostic
329*46061Scorbett return (p);
33039777Sbostic }
33139777Sbostic
33239777Sbostic
33339777Sbostic /* show_cores is used for debugging */
33439777Sbostic
show_cores()33539777Sbostic show_cores()
33639777Sbostic {
33739777Sbostic core *p;
33839777Sbostic int i, j, k, n;
33939777Sbostic int itemno;
34039777Sbostic
34139777Sbostic k = 0;
34239777Sbostic for (p = first_state; p; ++k, p = p->next)
34339777Sbostic {
34439777Sbostic if (k) printf("\n");
34539777Sbostic printf("state %d, number = %d, accessing symbol = %s\n",
34639777Sbostic k, p->number, symbol_name[p->accessing_symbol]);
34739777Sbostic n = p->nitems;
34839777Sbostic for (i = 0; i < n; ++i)
34939777Sbostic {
35039777Sbostic itemno = p->items[i];
35139777Sbostic printf("%4d ", itemno);
35239777Sbostic j = itemno;
35339777Sbostic while (ritem[j] >= 0) ++j;
35439777Sbostic printf("%s :", symbol_name[rlhs[-ritem[j]]]);
35539777Sbostic j = rrhs[-ritem[j]];
35639777Sbostic while (j < itemno)
35739777Sbostic printf(" %s", symbol_name[ritem[j++]]);
35839777Sbostic printf(" .");
35939777Sbostic while (ritem[j] >= 0)
36039777Sbostic printf(" %s", symbol_name[ritem[j++]]);
36139777Sbostic printf("\n");
36239777Sbostic fflush(stdout);
36339777Sbostic }
36439777Sbostic }
36539777Sbostic }
36639777Sbostic
36739777Sbostic
36839777Sbostic /* show_ritems is used for debugging */
36939777Sbostic
show_ritems()37039777Sbostic show_ritems()
37139777Sbostic {
37239777Sbostic int i;
37339777Sbostic
37439777Sbostic for (i = 0; i < nitems; ++i)
37539777Sbostic printf("ritem[%d] = %d\n", i, ritem[i]);
37639777Sbostic }
37739777Sbostic
37839777Sbostic
37939777Sbostic /* show_rrhs is used for debugging */
show_rrhs()38039777Sbostic show_rrhs()
38139777Sbostic {
38239777Sbostic int i;
38339777Sbostic
38439777Sbostic for (i = 0; i < nrules; ++i)
38539777Sbostic printf("rrhs[%d] = %d\n", i, rrhs[i]);
38639777Sbostic }
38739777Sbostic
38839777Sbostic
38939777Sbostic /* show_shifts is used for debugging */
39039777Sbostic
show_shifts()39139777Sbostic show_shifts()
39239777Sbostic {
39339777Sbostic shifts *p;
39439777Sbostic int i, j, k;
39539777Sbostic
39639777Sbostic k = 0;
39739777Sbostic for (p = first_shift; p; ++k, p = p->next)
39839777Sbostic {
39939777Sbostic if (k) printf("\n");
40039777Sbostic printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
40139777Sbostic p->nshifts);
40239777Sbostic j = p->nshifts;
40339777Sbostic for (i = 0; i < j; ++i)
40439777Sbostic printf("\t%d\n", p->shift[i]);
40539777Sbostic }
40639777Sbostic }
40739777Sbostic
40839777Sbostic
save_shifts()40939777Sbostic save_shifts()
41039777Sbostic {
411*46061Scorbett register shifts *p;
412*46061Scorbett register short *sp1;
413*46061Scorbett register short *sp2;
414*46061Scorbett register short *send;
41539777Sbostic
416*46061Scorbett p = (shifts *) allocate((unsigned) (sizeof(shifts) +
41739777Sbostic (nshifts - 1) * sizeof(short)));
41839777Sbostic
419*46061Scorbett p->number = this_state->number;
420*46061Scorbett p->nshifts = nshifts;
42139777Sbostic
422*46061Scorbett sp1 = shiftset;
423*46061Scorbett sp2 = p->shift;
424*46061Scorbett send = shiftset + nshifts;
42539777Sbostic
426*46061Scorbett while (sp1 < send)
427*46061Scorbett *sp2++ = *sp1++;
42839777Sbostic
429*46061Scorbett if (last_shift)
43039777Sbostic {
431*46061Scorbett last_shift->next = p;
432*46061Scorbett last_shift = p;
43339777Sbostic }
434*46061Scorbett else
43539777Sbostic {
436*46061Scorbett first_shift = p;
437*46061Scorbett last_shift = p;
43839777Sbostic }
43939777Sbostic }
44039777Sbostic
44139777Sbostic
44239777Sbostic
save_reductions()44339777Sbostic save_reductions()
44439777Sbostic {
445*46061Scorbett register short *isp;
446*46061Scorbett register short *rp1;
447*46061Scorbett register short *rp2;
448*46061Scorbett register int item;
449*46061Scorbett register int count;
450*46061Scorbett register reductions *p;
451*46061Scorbett register short *rend;
45239777Sbostic
453*46061Scorbett count = 0;
454*46061Scorbett for (isp = itemset; isp < itemsetend; isp++)
45539777Sbostic {
456*46061Scorbett item = ritem[*isp];
457*46061Scorbett if (item < 0)
45839777Sbostic {
459*46061Scorbett redset[count++] = -item;
46039777Sbostic }
46139777Sbostic }
46239777Sbostic
463*46061Scorbett if (count)
46439777Sbostic {
465*46061Scorbett p = (reductions *) allocate((unsigned) (sizeof(reductions) +
46639777Sbostic (count - 1) * sizeof(short)));
46739777Sbostic
468*46061Scorbett p->number = this_state->number;
469*46061Scorbett p->nreds = count;
47039777Sbostic
471*46061Scorbett rp1 = redset;
472*46061Scorbett rp2 = p->rules;
473*46061Scorbett rend = rp1 + count;
47439777Sbostic
475*46061Scorbett while (rp1 < rend)
476*46061Scorbett *rp2++ = *rp1++;
47739777Sbostic
478*46061Scorbett if (last_reduction)
47939777Sbostic {
480*46061Scorbett last_reduction->next = p;
481*46061Scorbett last_reduction = p;
48239777Sbostic }
483*46061Scorbett else
48439777Sbostic {
485*46061Scorbett first_reduction = p;
486*46061Scorbett last_reduction = p;
48739777Sbostic }
48839777Sbostic }
48939777Sbostic }
49039777Sbostic
49139777Sbostic
set_derives()49239777Sbostic set_derives()
49339777Sbostic {
494*46061Scorbett register int i, k;
495*46061Scorbett register int lhs;
496*46061Scorbett register short *rules;
49739777Sbostic
498*46061Scorbett derives = NEW2(nsyms, short *);
499*46061Scorbett rules = NEW2(nvars + nrules, short);
50039777Sbostic
501*46061Scorbett k = 0;
502*46061Scorbett for (lhs = start_symbol; lhs < nsyms; lhs++)
50339777Sbostic {
504*46061Scorbett derives[lhs] = rules + k;
505*46061Scorbett for (i = 0; i < nrules; i++)
50639777Sbostic {
507*46061Scorbett if (rlhs[i] == lhs)
50839777Sbostic {
509*46061Scorbett rules[k] = i;
510*46061Scorbett k++;
51139777Sbostic }
51239777Sbostic }
513*46061Scorbett rules[k] = -1;
514*46061Scorbett k++;
51539777Sbostic }
51639777Sbostic
51739777Sbostic #ifdef DEBUG
518*46061Scorbett print_derives();
51939777Sbostic #endif
52039777Sbostic }
52139777Sbostic
free_derives()52239777Sbostic free_derives()
52339777Sbostic {
524*46061Scorbett FREE(derives[start_symbol]);
525*46061Scorbett FREE(derives);
52639777Sbostic }
52739777Sbostic
52839777Sbostic #ifdef DEBUG
print_derives()52939777Sbostic print_derives()
53039777Sbostic {
531*46061Scorbett register int i;
532*46061Scorbett register short *sp;
53339777Sbostic
534*46061Scorbett printf("\nDERIVES\n\n");
53539777Sbostic
536*46061Scorbett for (i = start_symbol; i < nsyms; i++)
53739777Sbostic {
538*46061Scorbett printf("%s derives ", symbol_name[i]);
539*46061Scorbett for (sp = derives[i]; *sp >= 0; sp++)
54039777Sbostic {
541*46061Scorbett printf(" %d", *sp);
54239777Sbostic }
543*46061Scorbett putchar('\n');
54439777Sbostic }
54539777Sbostic
546*46061Scorbett putchar('\n');
54739777Sbostic }
54839777Sbostic #endif
54939777Sbostic
55039777Sbostic
set_nullable()55139777Sbostic set_nullable()
55239777Sbostic {
55339777Sbostic register int i, j;
55439777Sbostic register int empty;
55539777Sbostic int done;
55639777Sbostic
55739777Sbostic nullable = MALLOC(nsyms);
55839777Sbostic if (nullable == 0) no_space();
55939777Sbostic
56039777Sbostic for (i = 0; i < nsyms; ++i)
56139777Sbostic nullable[i] = 0;
56239777Sbostic
56339777Sbostic done = 0;
56439777Sbostic while (!done)
56539777Sbostic {
56639777Sbostic done = 1;
56739777Sbostic for (i = 1; i < nitems; i++)
56839777Sbostic {
56939777Sbostic empty = 1;
57039777Sbostic while ((j = ritem[i]) >= 0)
57139777Sbostic {
57239777Sbostic if (!nullable[j])
57339777Sbostic empty = 0;
57439777Sbostic ++i;
57539777Sbostic }
57639777Sbostic if (empty)
57739777Sbostic {
57839777Sbostic j = rlhs[-j];
57939777Sbostic if (!nullable[j])
58039777Sbostic {
58139777Sbostic nullable[j] = 1;
58239777Sbostic done = 0;
58339777Sbostic }
58439777Sbostic }
58539777Sbostic }
58639777Sbostic }
58739777Sbostic
58839777Sbostic #ifdef DEBUG
58939777Sbostic for (i = 0; i < nsyms; i++)
59039777Sbostic {
59139777Sbostic if (nullable[i])
59239777Sbostic printf("%s is nullable\n", symbol_name[i]);
59339777Sbostic else
59439777Sbostic printf("%s is not nullable\n", symbol_name[i]);
59539777Sbostic }
59639777Sbostic #endif
59739777Sbostic }
59839777Sbostic
59939777Sbostic
free_nullable()60039777Sbostic free_nullable()
60139777Sbostic {
602*46061Scorbett FREE(nullable);
60339777Sbostic }
60439777Sbostic
60539777Sbostic
lr0()60639777Sbostic lr0()
60739777Sbostic {
60839777Sbostic set_derives();
60939777Sbostic set_nullable();
61039777Sbostic generate_states();
61139777Sbostic }
612