Annotation of src/usr.bin/yacc/lr0.c, Revision 1.9
1.9 ! deraadt 1: /* $OpenBSD: lr0.c,v 1.8 2003/06/19 16:34:53 pvalchev Exp $ */
1.2 deraadt 2: /* $NetBSD: lr0.c,v 1.4 1996/03/19 03:21:35 jtc Exp $ */
3:
4: /*
5: * Copyright (c) 1989 The Regents of the University of California.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Robert Paul Corbett.
10: *
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.
1.7 millert 19: * 3. Neither the name of the University nor the names of its contributors
1.2 deraadt 20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
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.
34: */
1.1 deraadt 35:
36: #include "defs.h"
37:
38: extern short *itemset;
39: extern short *itemsetend;
40: extern unsigned *ruleset;
41:
42: int nstates;
43: core *first_state;
44: shifts *first_shift;
45: reductions *first_reduction;
46:
1.6 millert 47: int get_state(int);
48: core *new_state(int);
1.4 pvalchev 49:
1.6 millert 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 show_cores(void);
58: void show_ritems(void);
59: void show_rrhs(void);
60: void show_shifts(void);
61: void save_shifts(void);
62: void save_reductions(void);
63: void set_derives(void);
64: void print_derives(void);
65: void set_nullable(void);
66: void free_derives(void);
67: void free_nullable(void);
1.1 deraadt 68:
69: static core **state_set;
70: static core *this_state;
71: static core *last_state;
72: static shifts *last_shift;
73: static reductions *last_reduction;
74:
75: static int nshifts;
76: static short *shift_symbol;
77:
78: static short *redset;
79: static short *shiftset;
80:
81: static short **kernel_base;
82: static short **kernel_end;
83: static short *kernel_items;
84:
1.4 pvalchev 85: void
1.8 pvalchev 86: allocate_itemsets(void)
1.1 deraadt 87: {
1.5 mpech 88: short *itemp;
89: short *item_end;
90: int symbol;
91: int i;
92: int count;
93: int max;
94: short *symbol_count;
1.1 deraadt 95:
96: count = 0;
97: symbol_count = NEW2(nsyms, short);
98:
99: item_end = ritem + nitems;
100: for (itemp = ritem; itemp < item_end; itemp++)
101: {
102: symbol = *itemp;
103: if (symbol >= 0)
104: {
105: count++;
106: symbol_count[symbol]++;
107: }
108: }
109:
110: kernel_base = NEW2(nsyms, short *);
111: kernel_items = NEW2(count, short);
112:
113: count = 0;
114: max = 0;
115: for (i = 0; i < nsyms; i++)
116: {
117: kernel_base[i] = kernel_items + count;
118: count += symbol_count[i];
119: if (max < symbol_count[i])
120: max = symbol_count[i];
121: }
122:
123: shift_symbol = symbol_count;
124: kernel_end = NEW2(nsyms, short *);
125: }
126:
1.4 pvalchev 127: void
1.8 pvalchev 128: allocate_storage(void)
1.1 deraadt 129: {
130: allocate_itemsets();
131: shiftset = NEW2(nsyms, short);
132: redset = NEW2(nrules + 1, short);
133: state_set = NEW2(nitems, core *);
134: }
135:
1.4 pvalchev 136: void
1.8 pvalchev 137: append_states(void)
1.1 deraadt 138: {
1.5 mpech 139: int i;
140: int j;
141: int symbol;
1.1 deraadt 142:
143: #ifdef TRACE
144: fprintf(stderr, "Entering append_states()\n");
145: #endif
146: for (i = 1; i < nshifts; i++)
147: {
148: symbol = shift_symbol[i];
149: j = i;
150: while (j > 0 && shift_symbol[j - 1] > symbol)
151: {
152: shift_symbol[j] = shift_symbol[j - 1];
153: j--;
154: }
155: shift_symbol[j] = symbol;
156: }
157:
158: for (i = 0; i < nshifts; i++)
159: {
160: symbol = shift_symbol[i];
161: shiftset[i] = get_state(symbol);
162: }
163: }
164:
1.4 pvalchev 165: void
1.8 pvalchev 166: free_storage(void)
1.1 deraadt 167: {
168: FREE(shift_symbol);
169: FREE(redset);
170: FREE(shiftset);
171: FREE(kernel_base);
172: FREE(kernel_end);
173: FREE(kernel_items);
174: FREE(state_set);
175: }
176:
177:
1.4 pvalchev 178: void
1.8 pvalchev 179: generate_states(void)
1.1 deraadt 180: {
181: allocate_storage();
182: itemset = NEW2(nitems, short);
183: ruleset = NEW2(WORDSIZE(nrules), unsigned);
184: set_first_derives();
185: initialize_states();
186:
187: while (this_state)
188: {
189: closure(this_state->items, this_state->nitems);
190: save_reductions();
191: new_itemsets();
192: append_states();
193:
194: if (nshifts > 0)
195: save_shifts();
196:
197: this_state = this_state->next;
198: }
199:
200: finalize_closure();
201: free_storage();
202: }
203:
204:
205:
206: int
1.8 pvalchev 207: get_state(int symbol)
1.1 deraadt 208: {
1.5 mpech 209: int key;
210: short *isp1;
211: short *isp2;
212: short *iend;
213: core *sp;
214: int found;
215: int n;
1.1 deraadt 216:
217: #ifdef TRACE
218: fprintf(stderr, "Entering get_state(%d)\n", symbol);
219: #endif
220:
221: isp1 = kernel_base[symbol];
222: iend = kernel_end[symbol];
223: n = iend - isp1;
224:
225: key = *isp1;
226: assert(0 <= key && key < nitems);
227: sp = state_set[key];
228: if (sp)
229: {
230: found = 0;
231: while (!found)
232: {
233: if (sp->nitems == n)
234: {
235: found = 1;
236: isp1 = kernel_base[symbol];
237: isp2 = sp->items;
238:
239: while (found && isp1 < iend)
240: {
241: if (*isp1++ != *isp2++)
242: found = 0;
243: }
244: }
245:
246: if (!found)
247: {
248: if (sp->link)
249: {
250: sp = sp->link;
251: }
252: else
253: {
254: sp = sp->link = new_state(symbol);
255: found = 1;
256: }
257: }
258: }
259: }
260: else
261: {
262: state_set[key] = sp = new_state(symbol);
263: }
264:
265: return (sp->number);
266: }
267:
268:
1.4 pvalchev 269: void
1.8 pvalchev 270: initialize_states(void)
1.1 deraadt 271: {
1.5 mpech 272: int i;
273: short *start_derives;
274: core *p;
1.1 deraadt 275:
276: start_derives = derives[start_symbol];
277: for (i = 0; start_derives[i] >= 0; ++i)
278: continue;
279:
280: p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
281: if (p == 0) no_space();
282:
283: p->next = 0;
284: p->link = 0;
285: p->number = 0;
286: p->accessing_symbol = 0;
287: p->nitems = i;
288:
289: for (i = 0; start_derives[i] >= 0; ++i)
290: p->items[i] = rrhs[start_derives[i]];
291:
292: first_state = last_state = this_state = p;
293: nstates = 1;
294: }
295:
1.4 pvalchev 296: void
1.8 pvalchev 297: new_itemsets(void)
1.1 deraadt 298: {
1.5 mpech 299: int i;
300: int shiftcount;
301: short *isp;
302: short *ksp;
303: int symbol;
1.1 deraadt 304:
305: for (i = 0; i < nsyms; i++)
306: kernel_end[i] = 0;
307:
308: shiftcount = 0;
309: isp = itemset;
310: while (isp < itemsetend)
311: {
312: i = *isp++;
313: symbol = ritem[i];
314: if (symbol > 0)
315: {
316: ksp = kernel_end[symbol];
317: if (!ksp)
318: {
319: shift_symbol[shiftcount++] = symbol;
320: ksp = kernel_base[symbol];
321: }
322:
323: *ksp++ = i + 1;
324: kernel_end[symbol] = ksp;
325: }
326: }
327:
328: nshifts = shiftcount;
329: }
330:
331:
332:
333: core *
1.8 pvalchev 334: new_state(int symbol)
1.1 deraadt 335: {
1.5 mpech 336: int n;
337: core *p;
338: short *isp1;
339: short *isp2;
340: short *iend;
1.1 deraadt 341:
342: #ifdef TRACE
343: fprintf(stderr, "Entering new_state(%d)\n", symbol);
344: #endif
345:
346: if (nstates >= MAXSHORT)
347: fatal("too many states");
348:
349: isp1 = kernel_base[symbol];
350: iend = kernel_end[symbol];
351: n = iend - isp1;
352:
353: p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
354: p->accessing_symbol = symbol;
355: p->number = nstates;
356: p->nitems = n;
357:
358: isp2 = p->items;
359: while (isp1 < iend)
360: *isp2++ = *isp1++;
361:
362: last_state->next = p;
363: last_state = p;
364:
365: nstates++;
366:
367: return (p);
368: }
369:
370:
371: /* show_cores is used for debugging */
372:
1.4 pvalchev 373: void
1.8 pvalchev 374: show_cores(void)
1.1 deraadt 375: {
376: core *p;
377: int i, j, k, n;
378: int itemno;
379:
380: k = 0;
381: for (p = first_state; p; ++k, p = p->next)
382: {
383: if (k) printf("\n");
384: printf("state %d, number = %d, accessing symbol = %s\n",
385: k, p->number, symbol_name[p->accessing_symbol]);
386: n = p->nitems;
387: for (i = 0; i < n; ++i)
388: {
389: itemno = p->items[i];
390: printf("%4d ", itemno);
391: j = itemno;
392: while (ritem[j] >= 0) ++j;
393: printf("%s :", symbol_name[rlhs[-ritem[j]]]);
394: j = rrhs[-ritem[j]];
395: while (j < itemno)
396: printf(" %s", symbol_name[ritem[j++]]);
397: printf(" .");
398: while (ritem[j] >= 0)
399: printf(" %s", symbol_name[ritem[j++]]);
400: printf("\n");
401: fflush(stdout);
402: }
403: }
404: }
405:
406:
407: /* show_ritems is used for debugging */
408:
1.4 pvalchev 409: void
1.8 pvalchev 410: show_ritems(void)
1.1 deraadt 411: {
412: int i;
413:
414: for (i = 0; i < nitems; ++i)
415: printf("ritem[%d] = %d\n", i, ritem[i]);
416: }
417:
418:
419: /* show_rrhs is used for debugging */
1.4 pvalchev 420:
421: void
1.8 pvalchev 422: show_rrhs(void)
1.1 deraadt 423: {
424: int i;
425:
426: for (i = 0; i < nrules; ++i)
427: printf("rrhs[%d] = %d\n", i, rrhs[i]);
428: }
429:
430:
431: /* show_shifts is used for debugging */
432:
1.4 pvalchev 433: void
1.8 pvalchev 434: show_shifts(void)
1.1 deraadt 435: {
436: shifts *p;
437: int i, j, k;
438:
439: k = 0;
440: for (p = first_shift; p; ++k, p = p->next)
441: {
442: if (k) printf("\n");
443: printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
444: p->nshifts);
445: j = p->nshifts;
446: for (i = 0; i < j; ++i)
447: printf("\t%d\n", p->shift[i]);
448: }
449: }
450:
1.4 pvalchev 451: void
1.8 pvalchev 452: save_shifts(void)
1.1 deraadt 453: {
1.5 mpech 454: shifts *p;
455: short *sp1;
456: short *sp2;
457: short *send;
1.1 deraadt 458:
459: p = (shifts *) allocate((unsigned) (sizeof(shifts) +
460: (nshifts - 1) * sizeof(short)));
461:
462: p->number = this_state->number;
463: p->nshifts = nshifts;
464:
465: sp1 = shiftset;
466: sp2 = p->shift;
467: send = shiftset + nshifts;
468:
469: while (sp1 < send)
470: *sp2++ = *sp1++;
471:
472: if (last_shift)
473: {
474: last_shift->next = p;
475: last_shift = p;
476: }
477: else
478: {
479: first_shift = p;
480: last_shift = p;
481: }
482: }
483:
484:
1.4 pvalchev 485: void
1.8 pvalchev 486: save_reductions(void)
1.1 deraadt 487: {
1.5 mpech 488: short *isp;
489: short *rp1;
490: short *rp2;
491: int item;
492: int count;
493: reductions *p;
494: short *rend;
1.1 deraadt 495:
496: count = 0;
497: for (isp = itemset; isp < itemsetend; isp++)
498: {
499: item = ritem[*isp];
500: if (item < 0)
501: {
502: redset[count++] = -item;
503: }
504: }
505:
506: if (count)
507: {
508: p = (reductions *) allocate((unsigned) (sizeof(reductions) +
509: (count - 1) * sizeof(short)));
510:
511: p->number = this_state->number;
512: p->nreds = count;
513:
514: rp1 = redset;
515: rp2 = p->rules;
516: rend = rp1 + count;
517:
518: while (rp1 < rend)
519: *rp2++ = *rp1++;
520:
521: if (last_reduction)
522: {
523: last_reduction->next = p;
524: last_reduction = p;
525: }
526: else
527: {
528: first_reduction = p;
529: last_reduction = p;
530: }
531: }
532: }
533:
1.4 pvalchev 534: void
1.8 pvalchev 535: set_derives(void)
1.1 deraadt 536: {
1.5 mpech 537: int i, k;
538: int lhs;
539: short *rules;
1.1 deraadt 540:
541: derives = NEW2(nsyms, short *);
542: rules = NEW2(nvars + nrules, short);
543:
544: k = 0;
545: for (lhs = start_symbol; lhs < nsyms; lhs++)
546: {
547: derives[lhs] = rules + k;
548: for (i = 0; i < nrules; i++)
549: {
550: if (rlhs[i] == lhs)
551: {
552: rules[k] = i;
553: k++;
554: }
555: }
556: rules[k] = -1;
557: k++;
558: }
559:
560: #ifdef DEBUG
561: print_derives();
562: #endif
563: }
564:
1.4 pvalchev 565: void
1.8 pvalchev 566: free_derives(void)
1.1 deraadt 567: {
568: FREE(derives[start_symbol]);
569: FREE(derives);
570: }
571:
572: #ifdef DEBUG
1.4 pvalchev 573: void
1.8 pvalchev 574: print_derives(void)
1.1 deraadt 575: {
1.5 mpech 576: int i;
577: short *sp;
1.1 deraadt 578:
579: printf("\nDERIVES\n\n");
580:
581: for (i = start_symbol; i < nsyms; i++)
582: {
583: printf("%s derives ", symbol_name[i]);
584: for (sp = derives[i]; *sp >= 0; sp++)
585: {
586: printf(" %d", *sp);
587: }
588: putchar('\n');
589: }
590:
591: putchar('\n');
592: }
593: #endif
594:
1.4 pvalchev 595: void
1.8 pvalchev 596: set_nullable(void)
1.1 deraadt 597: {
1.5 mpech 598: int i, j;
599: int empty;
1.1 deraadt 600: int done;
601:
602: nullable = MALLOC(nsyms);
603: if (nullable == 0) no_space();
604:
605: for (i = 0; i < nsyms; ++i)
606: nullable[i] = 0;
607:
608: done = 0;
609: while (!done)
610: {
611: done = 1;
612: for (i = 1; i < nitems; i++)
613: {
614: empty = 1;
615: while ((j = ritem[i]) >= 0)
616: {
617: if (!nullable[j])
618: empty = 0;
619: ++i;
620: }
621: if (empty)
622: {
623: j = rlhs[-j];
624: if (!nullable[j])
625: {
626: nullable[j] = 1;
627: done = 0;
628: }
629: }
630: }
631: }
632:
633: #ifdef DEBUG
634: for (i = 0; i < nsyms; i++)
635: {
636: if (nullable[i])
637: printf("%s is nullable\n", symbol_name[i]);
638: else
639: printf("%s is not nullable\n", symbol_name[i]);
640: }
641: #endif
642: }
643:
1.4 pvalchev 644: void
1.8 pvalchev 645: free_nullable(void)
1.1 deraadt 646: {
647: FREE(nullable);
648: }
649:
1.4 pvalchev 650: void
1.8 pvalchev 651: lr0(void)
1.1 deraadt 652: {
653: set_derives();
654: set_nullable();
655: generate_states();
656: }