Merge commit '8c331166625387ef510c183eb42ba2dec1af7a0d' into merges
[unleashed.git] / bin / yacc / lr0.c
blobc22da118e3d76512d45637d0f8f2231211111e21
1 /* $OpenBSD: lr0.c,v 1.18 2014/03/13 01:18:22 tedu Exp $ */
2 /* $NetBSD: lr0.c,v 1.4 1996/03/19 03:21:35 jtc Exp $ */
4 /*
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Robert Paul Corbett.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
36 #include "defs.h"
38 extern short *itemset;
39 extern short *itemsetend;
40 extern unsigned *ruleset;
42 int nstates;
43 core *first_state;
44 shifts *first_shift;
45 reductions *first_reduction;
47 short get_state(int);
48 core *new_state(int);
50 void allocate_itemsets(void);
51 void allocate_storage(void);
52 void append_states(void);
53 void free_storage(void);
54 void generate_states(void);
55 void initialize_states(void);
56 void new_itemsets(void);
57 void save_shifts(void);
58 void save_reductions(void);
59 void set_derives(void);
60 void print_derives(void);
61 void set_nullable(void);
63 static core **state_set;
64 static core *this_state;
65 static core *last_state;
66 static shifts *last_shift;
67 static reductions *last_reduction;
69 static int nshifts;
70 static short *shift_symbol;
72 static short *redset;
73 static short *shiftset;
75 static short **kernel_base;
76 static short **kernel_end;
77 static short *kernel_items;
79 void
80 allocate_itemsets(void)
82 short *itemp, *item_end;
83 int i, count, max, symbol;
84 short *symbol_count;
86 count = 0;
87 symbol_count = NEW2(nsyms, short);
89 item_end = ritem + nitems;
90 for (itemp = ritem; itemp < item_end; itemp++) {
91 symbol = *itemp;
92 if (symbol >= 0) {
93 count++;
94 symbol_count[symbol]++;
98 kernel_base = NEW2(nsyms, short *);
99 kernel_items = NEW2(count, short);
101 count = 0;
102 max = 0;
103 for (i = 0; i < nsyms; i++) {
104 kernel_base[i] = kernel_items + count;
105 count += symbol_count[i];
106 if (max < symbol_count[i])
107 max = symbol_count[i];
110 shift_symbol = symbol_count;
111 kernel_end = NEW2(nsyms, short *);
114 void
115 allocate_storage(void)
117 allocate_itemsets();
118 shiftset = NEW2(nsyms, short);
119 redset = NEW2(nrules + 1, short);
120 state_set = NEW2(nitems, core *);
123 void
124 append_states(void)
126 int i, j, symbol;
128 #ifdef TRACE
129 fprintf(stderr, "Entering append_states()\n");
130 #endif
131 for (i = 1; i < nshifts; i++) {
132 symbol = shift_symbol[i];
133 j = i;
134 while (j > 0 && shift_symbol[j - 1] > symbol) {
135 shift_symbol[j] = shift_symbol[j - 1];
136 j--;
138 shift_symbol[j] = symbol;
141 for (i = 0; i < nshifts; i++) {
142 symbol = shift_symbol[i];
143 shiftset[i] = get_state(symbol);
147 void
148 free_storage(void)
150 free(shift_symbol);
151 free(redset);
152 free(shiftset);
153 free(kernel_base);
154 free(kernel_end);
155 free(kernel_items);
156 free(state_set);
160 void
161 generate_states(void)
163 allocate_storage();
164 itemset = NEW2(nitems, short);
165 ruleset = NEW2(WORDSIZE(nrules), unsigned);
166 set_first_derives();
167 initialize_states();
169 while (this_state) {
170 closure(this_state->items, this_state->nitems);
171 save_reductions();
172 new_itemsets();
173 append_states();
175 if (nshifts > 0)
176 save_shifts();
178 this_state = this_state->next;
181 finalize_closure();
182 free_storage();
187 short
188 get_state(int symbol)
190 int n, found, key;
191 short *isp1, *isp2, *iend;
192 core *sp;
194 #ifdef TRACE
195 fprintf(stderr, "Entering get_state(%d)\n", symbol);
196 #endif
198 isp1 = kernel_base[symbol];
199 iend = kernel_end[symbol];
200 n = iend - isp1;
202 key = *isp1;
203 assert(0 <= key && key < nitems);
204 sp = state_set[key];
205 if (sp) {
206 found = 0;
207 while (!found) {
208 if (sp->nitems == n) {
209 found = 1;
210 isp1 = kernel_base[symbol];
211 isp2 = sp->items;
213 while (found && isp1 < iend) {
214 if (*isp1++ != *isp2++)
215 found = 0;
218 if (!found) {
219 if (sp->link) {
220 sp = sp->link;
221 } else {
222 sp = sp->link = new_state(symbol);
223 found = 1;
227 } else {
228 state_set[key] = sp = new_state(symbol);
231 return (sp->number);
235 void
236 initialize_states(void)
238 int i;
239 short *start_derives;
240 core *p;
242 start_derives = derives[start_symbol];
243 for (i = 0; start_derives[i] >= 0; ++i)
244 continue;
246 p = malloc(sizeof(core) + i * sizeof(short));
247 if (p == NULL)
248 no_space();
250 p->next = 0;
251 p->link = 0;
252 p->number = 0;
253 p->accessing_symbol = 0;
254 p->nitems = i;
256 for (i = 0; start_derives[i] >= 0; ++i)
257 p->items[i] = rrhs[start_derives[i]];
259 first_state = last_state = this_state = p;
260 nstates = 1;
263 void
264 new_itemsets(void)
266 int i, shiftcount;
267 short *isp, *ksp;
268 int symbol;
270 memset(kernel_end, 0, nsyms * sizeof(short *));
272 shiftcount = 0;
273 isp = itemset;
274 while (isp < itemsetend) {
275 i = *isp++;
276 symbol = ritem[i];
277 if (symbol > 0) {
278 ksp = kernel_end[symbol];
279 if (!ksp) {
280 shift_symbol[shiftcount++] = symbol;
281 ksp = kernel_base[symbol];
283 *ksp++ = i + 1;
284 kernel_end[symbol] = ksp;
288 nshifts = shiftcount;
293 core *
294 new_state(int symbol)
296 int n;
297 core *p;
298 short *isp1, *isp2, *iend;
300 #ifdef TRACE
301 fprintf(stderr, "Entering new_state(%d)\n", symbol);
302 #endif
304 if (nstates >= MAXSHORT)
305 fatal("too many states");
307 isp1 = kernel_base[symbol];
308 iend = kernel_end[symbol];
309 n = iend - isp1;
311 p = allocate(sizeof(core) + (n - 1) * sizeof(short));
312 p->accessing_symbol = symbol;
313 p->number = nstates;
314 p->nitems = n;
316 isp2 = p->items;
317 while (isp1 < iend)
318 *isp2++ = *isp1++;
320 last_state->next = p;
321 last_state = p;
323 nstates++;
325 return (p);
329 void
330 save_shifts(void)
332 shifts *p;
333 short *sp1, *sp2, *send;
335 p = allocate(sizeof(shifts) + (nshifts - 1) * sizeof(short));
337 p->number = this_state->number;
338 p->nshifts = nshifts;
340 sp1 = shiftset;
341 sp2 = p->shift;
342 send = shiftset + nshifts;
344 while (sp1 < send)
345 *sp2++ = *sp1++;
347 if (last_shift) {
348 last_shift->next = p;
349 last_shift = p;
350 } else {
351 first_shift = p;
352 last_shift = p;
357 void
358 save_reductions(void)
360 short *isp, *rp1, *rp2;
361 int item, count;
362 reductions *p;
363 short *rend;
365 count = 0;
366 for (isp = itemset; isp < itemsetend; isp++) {
367 item = ritem[*isp];
368 if (item < 0) {
369 redset[count++] = -item;
373 if (count) {
374 p = allocate(sizeof(reductions) + (count - 1) * sizeof(short));
376 p->number = this_state->number;
377 p->nreds = count;
379 rp1 = redset;
380 rp2 = p->rules;
381 rend = rp1 + count;
383 while (rp1 < rend)
384 *rp2++ = *rp1++;
386 if (last_reduction) {
387 last_reduction->next = p;
388 last_reduction = p;
389 } else {
390 first_reduction = p;
391 last_reduction = p;
396 void
397 set_derives(void)
399 int i, k, lhs;
400 short *rules;
402 derives = NEW2(nsyms, short *);
403 rules = NEW2(nvars + nrules, short);
405 k = 0;
406 for (lhs = start_symbol; lhs < nsyms; lhs++) {
407 derives[lhs] = rules + k;
408 for (i = 0; i < nrules; i++) {
409 if (rlhs[i] == lhs) {
410 rules[k] = i;
411 k++;
414 rules[k] = -1;
415 k++;
418 #ifdef DEBUG
419 print_derives();
420 #endif
423 void
424 free_derives(void)
426 free(derives[start_symbol]);
427 free(derives);
430 #ifdef DEBUG
431 void
432 print_derives(void)
434 int i;
435 short *sp;
437 printf("\nDERIVES\n\n");
439 for (i = start_symbol; i < nsyms; i++) {
440 printf("%s derives ", symbol_name[i]);
441 for (sp = derives[i]; *sp >= 0; sp++) {
442 printf(" %d", *sp);
444 putchar('\n');
447 putchar('\n');
449 #endif
451 void
452 set_nullable(void)
454 int i, j;
455 int empty;
456 int done;
458 nullable = calloc(1, nsyms);
459 if (nullable == NULL)
460 no_space();
462 done = 0;
463 while (!done) {
464 done = 1;
465 for (i = 1; i < nitems; i++) {
466 empty = 1;
467 while ((j = ritem[i]) >= 0) {
468 if (!nullable[j])
469 empty = 0;
470 ++i;
472 if (empty) {
473 j = rlhs[-j];
474 if (!nullable[j]) {
475 nullable[j] = 1;
476 done = 0;
482 #ifdef DEBUG
483 for (i = 0; i < nsyms; i++) {
484 if (nullable[i])
485 printf("%s is nullable\n", symbol_name[i]);
486 else
487 printf("%s is not nullable\n", symbol_name[i]);
489 #endif
492 void
493 free_nullable(void)
495 free(nullable);
498 void
499 lr0(void)
501 set_derives();
502 set_nullable();
503 generate_states();