2 * Copyright (c) 1989 The Regents of the University of California.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * $FreeBSD: src/usr.bin/yacc/lr0.c,v 1.6 1999/08/28 01:08:00 peter Exp $
37 * $DragonFly: src/usr.bin/yacc/lr0.c,v 1.2 2003/06/17 04:29:34 dillon Exp $
39 * @(#)lr0.c 5.3 (Berkeley) 1/20/91
45 extern short *itemset;
46 extern short *itemsetend;
47 extern unsigned *ruleset;
52 reductions *first_reduction;
54 static void allocate_itemsets __P((void));
55 static void allocate_storage __P((void));
56 static void append_states __P((void));
57 static void free_storage __P((void));
58 static void generate_states __P((void));
59 static int get_state __P((int));
60 static void initialize_states __P((void));
61 static void new_itemsets __P((void));
62 static core *new_state __P((int));
64 static void print_derives __P((void));
66 static void save_reductions __P((void));
67 static void save_shifts __P((void));
68 static void set_derives __P((void));
69 static void set_nullable __P((void));
71 static core **state_set;
72 static core *this_state;
73 static core *last_state;
74 static shifts *last_shift;
75 static reductions *last_reduction;
78 static short *shift_symbol;
81 static short *shiftset;
83 static short **kernel_base;
84 static short **kernel_end;
85 static short *kernel_items;
91 register short *itemp;
92 register short *item_end;
97 register short *symbol_count;
100 symbol_count = NEW2(nsyms, short);
102 item_end = ritem + nitems;
103 for (itemp = ritem; itemp < item_end; itemp++)
109 symbol_count[symbol]++;
113 kernel_base = NEW2(nsyms, short *);
114 kernel_items = NEW2(count, short);
118 for (i = 0; i < nsyms; i++)
120 kernel_base[i] = kernel_items + count;
121 count += symbol_count[i];
122 if (max < symbol_count[i])
123 max = symbol_count[i];
126 shift_symbol = symbol_count;
127 kernel_end = NEW2(nsyms, short *);
135 shiftset = NEW2(nsyms, short);
136 redset = NEW2(nrules + 1, short);
137 state_set = NEW2(nitems, core *);
149 fprintf(stderr, "Entering append_states()\n");
151 for (i = 1; i < nshifts; i++)
153 symbol = shift_symbol[i];
155 while (j > 0 && shift_symbol[j - 1] > symbol)
157 shift_symbol[j] = shift_symbol[j - 1];
160 shift_symbol[j] = symbol;
163 for (i = 0; i < nshifts; i++)
165 symbol = shift_symbol[i];
166 shiftset[i] = get_state(symbol);
189 itemset = NEW2(nitems, short);
190 ruleset = NEW2(WORDSIZE(nrules), unsigned);
196 closure(this_state->items, this_state->nitems);
204 this_state = this_state->next;
218 register short *isp1;
219 register short *isp2;
220 register short *iend;
226 fprintf(stderr, "Entering get_state(%d)\n", symbol);
229 isp1 = kernel_base[symbol];
230 iend = kernel_end[symbol];
234 assert(0 <= key && key < nitems);
244 isp1 = kernel_base[symbol];
247 while (found && isp1 < iend)
249 if (*isp1++ != *isp2++)
262 sp = sp->link = new_state(symbol);
270 state_set[key] = sp = new_state(symbol);
282 register short *start_derives;
285 start_derives = derives[start_symbol];
286 for (i = 0; start_derives[i] >= 0; ++i)
289 p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
290 if (p == 0) no_space();
295 p->accessing_symbol = 0;
298 for (i = 0; start_derives[i] >= 0; ++i)
299 p->items[i] = rrhs[start_derives[i]];
301 first_state = last_state = this_state = p;
310 register int shiftcount;
315 for (i = 0; i < nsyms; i++)
320 while (isp < itemsetend)
326 ksp = kernel_end[symbol];
329 shift_symbol[shiftcount++] = symbol;
330 ksp = kernel_base[symbol];
334 kernel_end[symbol] = ksp;
338 nshifts = shiftcount;
349 register short *isp1;
350 register short *isp2;
351 register short *iend;
354 fprintf(stderr, "Entering new_state(%d)\n", symbol);
357 if (nstates >= MAXSHORT)
358 fatal("too many states");
360 isp1 = kernel_base[symbol];
361 iend = kernel_end[symbol];
364 p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
365 p->accessing_symbol = symbol;
373 last_state->next = p;
383 /* show_cores is used for debugging */
392 for (p = first_state; p; ++k, p = p->next)
395 printf("state %d, number = %d, accessing symbol = %s\n",
396 k, p->number, symbol_name[p->accessing_symbol]);
398 for (i = 0; i < n; ++i)
400 itemno = p->items[i];
401 printf("%4d ", itemno);
403 while (ritem[j] >= 0) ++j;
404 printf("%s :", symbol_name[rlhs[-ritem[j]]]);
407 printf(" %s", symbol_name[ritem[j++]]);
409 while (ritem[j] >= 0)
410 printf(" %s", symbol_name[ritem[j++]]);
418 /* show_ritems is used for debugging */
424 for (i = 0; i < nitems; ++i)
425 printf("ritem[%d] = %d\n", i, ritem[i]);
429 /* show_rrhs is used for debugging */
434 for (i = 0; i < nrules; ++i)
435 printf("rrhs[%d] = %d\n", i, rrhs[i]);
439 /* show_shifts is used for debugging */
447 for (p = first_shift; p; ++k, p = p->next)
450 printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
453 for (i = 0; i < j; ++i)
454 printf("\t%d\n", p->shift[i]);
466 register short *send;
468 p = (shifts *) allocate((unsigned) (sizeof(shifts) +
469 (nshifts - 1) * sizeof(short)));
471 p->number = this_state->number;
472 p->nshifts = nshifts;
476 send = shiftset + nshifts;
483 last_shift->next = p;
503 register reductions *p;
504 register short *rend;
507 for (isp = itemset; isp < itemsetend; isp++)
512 redset[count++] = -item;
518 p = (reductions *) allocate((unsigned) (sizeof(reductions) +
519 (count - 1) * sizeof(short)));
521 p->number = this_state->number;
533 last_reduction->next = p;
550 register short *rules;
552 derives = NEW2(nsyms, short *);
553 rules = NEW2(nvars + nrules, short);
556 for (lhs = start_symbol; lhs < nsyms; lhs++)
558 derives[lhs] = rules + k;
559 for (i = 0; i < nrules; i++)
579 FREE(derives[start_symbol]);
591 printf("\nDERIVES\n\n");
593 for (i = start_symbol; i < nsyms; i++)
595 printf("%s derives ", symbol_name[i]);
596 for (sp = derives[i]; *sp >= 0; sp++)
615 nullable = MALLOC(nsyms);
616 if (nullable == 0) no_space();
618 for (i = 0; i < nsyms; ++i)
625 for (i = 1; i < nitems; i++)
628 while ((j = ritem[i]) >= 0)
647 for (i = 0; i < nsyms; i++)
650 printf("%s is nullable\n", symbol_name[i]);
652 printf("%s is not nullable\n", symbol_name[i]);