2007-01-25 Chris Toshok <toshok@ximian.com>
[mcs.git] / jay / lr0.c
blob43106ea6cf39fc83076aa5d38d79d75bef7d2a09
1 /*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Robert Paul Corbett.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
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
34 * SUCH DAMAGE.
37 #ifndef lint
38 static char sccsid[] = "@(#)lr0.c 5.3 (Berkeley) 1/20/91";
39 #endif /* not lint */
41 #include "defs.h"
43 extern short *itemset;
44 extern short *itemsetend;
45 extern unsigned *ruleset;
47 int nstates;
48 core *first_state;
49 shifts *first_shift;
50 reductions *first_reduction;
52 int get_state();
53 core *new_state();
55 static core **state_set;
56 static core *this_state;
57 static core *last_state;
58 static shifts *last_shift;
59 static reductions *last_reduction;
61 static int nshifts;
62 static short *shift_symbol;
64 static short *redset;
65 static short *shiftset;
67 static short **kernel_base;
68 static short **kernel_end;
69 static short *kernel_items;
72 allocate_itemsets()
74 register short *itemp;
75 register short *item_end;
76 register int symbol;
77 register int i;
78 register int count;
79 register int max;
80 register short *symbol_count;
82 count = 0;
83 symbol_count = NEW2(nsyms, short);
85 item_end = ritem + nitems;
86 for (itemp = ritem; itemp < item_end; itemp++)
88 symbol = *itemp;
89 if (symbol >= 0)
91 count++;
92 symbol_count[symbol]++;
96 kernel_base = NEW2(nsyms, short *);
97 kernel_items = NEW2(count, short);
99 count = 0;
100 max = 0;
101 for (i = 0; i < nsyms; i++)
103 kernel_base[i] = kernel_items + count;
104 count += symbol_count[i];
105 if (max < symbol_count[i])
106 max = symbol_count[i];
109 shift_symbol = symbol_count;
110 kernel_end = NEW2(nsyms, short *);
114 allocate_storage()
116 allocate_itemsets();
117 shiftset = NEW2(nsyms, short);
118 redset = NEW2(nrules + 1, short);
119 state_set = NEW2(nitems, core *);
123 append_states()
125 register int i;
126 register int j;
127 register int symbol;
129 #ifdef TRACE
130 fprintf(stderr, "Entering append_states()\n");
131 #endif
132 for (i = 1; i < nshifts; i++)
134 symbol = shift_symbol[i];
135 j = i;
136 while (j > 0 && shift_symbol[j - 1] > symbol)
138 shift_symbol[j] = shift_symbol[j - 1];
139 j--;
141 shift_symbol[j] = symbol;
144 for (i = 0; i < nshifts; i++)
146 symbol = shift_symbol[i];
147 shiftset[i] = get_state(symbol);
152 free_storage()
154 FREE(shift_symbol);
155 FREE(redset);
156 FREE(shiftset);
157 FREE(kernel_base);
158 FREE(kernel_end);
159 FREE(kernel_items);
160 FREE(state_set);
165 generate_states()
167 allocate_storage();
168 itemset = NEW2(nitems, short);
169 ruleset = NEW2(WORDSIZE(nrules), unsigned);
170 set_first_derives();
171 initialize_states();
173 while (this_state)
175 closure(this_state->items, this_state->nitems);
176 save_reductions();
177 new_itemsets();
178 append_states();
180 if (nshifts > 0)
181 save_shifts();
183 this_state = this_state->next;
186 finalize_closure();
187 free_storage();
193 get_state(symbol)
194 int symbol;
196 register int key;
197 register short *isp1;
198 register short *isp2;
199 register short *iend;
200 register core *sp;
201 register int found;
202 register int n;
204 #ifdef TRACE
205 fprintf(stderr, "Entering get_state(%d)\n", symbol);
206 #endif
208 isp1 = kernel_base[symbol];
209 iend = kernel_end[symbol];
210 n = iend - isp1;
212 key = *isp1;
213 assert(0 <= key && key < nitems);
214 sp = state_set[key];
215 if (sp)
217 found = 0;
218 while (!found)
220 if (sp->nitems == n)
222 found = 1;
223 isp1 = kernel_base[symbol];
224 isp2 = sp->items;
226 while (found && isp1 < iend)
228 if (*isp1++ != *isp2++)
229 found = 0;
233 if (!found)
235 if (sp->link)
237 sp = sp->link;
239 else
241 sp = sp->link = new_state(symbol);
242 found = 1;
247 else
249 state_set[key] = sp = new_state(symbol);
252 return (sp->number);
257 initialize_states()
259 register int i;
260 register short *start_derives;
261 register core *p;
263 start_derives = derives[start_symbol];
264 for (i = 0; start_derives[i] >= 0; ++i)
265 continue;
267 p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
268 if (p == 0) no_space();
270 p->next = 0;
271 p->link = 0;
272 p->number = 0;
273 p->accessing_symbol = 0;
274 p->nitems = i;
276 for (i = 0; start_derives[i] >= 0; ++i)
277 p->items[i] = rrhs[start_derives[i]];
279 first_state = last_state = this_state = p;
280 nstates = 1;
284 new_itemsets()
286 register int i;
287 register int shiftcount;
288 register short *isp;
289 register short *ksp;
290 register int symbol;
292 for (i = 0; i < nsyms; i++)
293 kernel_end[i] = 0;
295 shiftcount = 0;
296 isp = itemset;
297 while (isp < itemsetend)
299 i = *isp++;
300 symbol = ritem[i];
301 if (symbol > 0)
303 ksp = kernel_end[symbol];
304 if (!ksp)
306 shift_symbol[shiftcount++] = symbol;
307 ksp = kernel_base[symbol];
310 *ksp++ = i + 1;
311 kernel_end[symbol] = ksp;
315 nshifts = shiftcount;
320 core *
321 new_state(symbol)
322 int symbol;
324 register int n;
325 register core *p;
326 register short *isp1;
327 register short *isp2;
328 register short *iend;
330 #ifdef TRACE
331 fprintf(stderr, "Entering new_state(%d)\n", symbol);
332 #endif
334 if (nstates >= MAXSHORT)
335 fatal("too many states");
337 isp1 = kernel_base[symbol];
338 iend = kernel_end[symbol];
339 n = iend - isp1;
341 p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
342 p->accessing_symbol = symbol;
343 p->number = nstates;
344 p->nitems = n;
346 isp2 = p->items;
347 while (isp1 < iend)
348 *isp2++ = *isp1++;
350 last_state->next = p;
351 last_state = p;
353 nstates++;
355 return (p);
359 /* show_cores is used for debugging */
361 show_cores()
363 core *p;
364 int i, j, k, n;
365 int itemno;
367 k = 0;
368 for (p = first_state; p; ++k, p = p->next)
370 if (k) printf("\n");
371 printf("state %d, number = %d, accessing symbol = %s\n",
372 k, p->number, symbol_name[p->accessing_symbol]);
373 n = p->nitems;
374 for (i = 0; i < n; ++i)
376 itemno = p->items[i];
377 printf("%4d ", itemno);
378 j = itemno;
379 while (ritem[j] >= 0) ++j;
380 printf("%s :", symbol_name[rlhs[-ritem[j]]]);
381 j = rrhs[-ritem[j]];
382 while (j < itemno)
383 printf(" %s", symbol_name[ritem[j++]]);
384 printf(" .");
385 while (ritem[j] >= 0)
386 printf(" %s", symbol_name[ritem[j++]]);
387 printf("\n");
388 fflush(stdout);
394 /* show_ritems is used for debugging */
396 show_ritems()
398 int i;
400 for (i = 0; i < nitems; ++i)
401 printf("ritem[%d] = %d\n", i, ritem[i]);
405 /* show_rrhs is used for debugging */
406 show_rrhs()
408 int i;
410 for (i = 0; i < nrules; ++i)
411 printf("rrhs[%d] = %d\n", i, rrhs[i]);
415 /* show_shifts is used for debugging */
417 show_shifts()
419 shifts *p;
420 int i, j, k;
422 k = 0;
423 for (p = first_shift; p; ++k, p = p->next)
425 if (k) printf("\n");
426 printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
427 p->nshifts);
428 j = p->nshifts;
429 for (i = 0; i < j; ++i)
430 printf("\t%d\n", p->shift[i]);
435 save_shifts()
437 register shifts *p;
438 register short *sp1;
439 register short *sp2;
440 register short *send;
442 p = (shifts *) allocate((unsigned) (sizeof(shifts) +
443 (nshifts - 1) * sizeof(short)));
445 p->number = this_state->number;
446 p->nshifts = nshifts;
448 sp1 = shiftset;
449 sp2 = p->shift;
450 send = shiftset + nshifts;
452 while (sp1 < send)
453 *sp2++ = *sp1++;
455 if (last_shift)
457 last_shift->next = p;
458 last_shift = p;
460 else
462 first_shift = p;
463 last_shift = p;
469 save_reductions()
471 register short *isp;
472 register short *rp1;
473 register short *rp2;
474 register int item;
475 register int count;
476 register reductions *p;
477 register short *rend;
479 count = 0;
480 for (isp = itemset; isp < itemsetend; isp++)
482 item = ritem[*isp];
483 if (item < 0)
485 redset[count++] = -item;
489 if (count)
491 p = (reductions *) allocate((unsigned) (sizeof(reductions) +
492 (count - 1) * sizeof(short)));
494 p->number = this_state->number;
495 p->nreds = count;
497 rp1 = redset;
498 rp2 = p->rules;
499 rend = rp1 + count;
501 while (rp1 < rend)
502 *rp2++ = *rp1++;
504 if (last_reduction)
506 last_reduction->next = p;
507 last_reduction = p;
509 else
511 first_reduction = p;
512 last_reduction = p;
518 set_derives()
520 register int i, k;
521 register int lhs;
522 register short *rules;
524 derives = NEW2(nsyms, short *);
525 rules = NEW2(nvars + nrules, short);
527 k = 0;
528 for (lhs = start_symbol; lhs < nsyms; lhs++)
530 derives[lhs] = rules + k;
531 for (i = 0; i < nrules; i++)
533 if (rlhs[i] == lhs)
535 rules[k] = i;
536 k++;
539 rules[k] = -1;
540 k++;
543 #ifdef DEBUG
544 print_derives();
545 #endif
548 free_derives()
550 FREE(derives[start_symbol]);
551 FREE(derives);
554 #ifdef DEBUG
555 print_derives()
557 register int i;
558 register short *sp;
560 printf("\nDERIVES\n\n");
562 for (i = start_symbol; i < nsyms; i++)
564 printf("%s derives ", symbol_name[i]);
565 for (sp = derives[i]; *sp >= 0; sp++)
567 printf(" %d", *sp);
569 putchar('\n');
572 putchar('\n');
574 #endif
577 set_nullable()
579 register int i, j;
580 register int empty;
581 int done;
583 nullable = MALLOC(nsyms);
584 if (nullable == 0) no_space();
586 for (i = 0; i < nsyms; ++i)
587 nullable[i] = 0;
589 done = 0;
590 while (!done)
592 done = 1;
593 for (i = 1; i < nitems; i++)
595 empty = 1;
596 while ((j = ritem[i]) >= 0)
598 if (!nullable[j])
599 empty = 0;
600 ++i;
602 if (empty)
604 j = rlhs[-j];
605 if (!nullable[j])
607 nullable[j] = 1;
608 done = 0;
614 #ifdef DEBUG
615 for (i = 0; i < nsyms; i++)
617 if (nullable[i])
618 printf("%s is nullable\n", symbol_name[i]);
619 else
620 printf("%s is not nullable\n", symbol_name[i]);
622 #endif
626 free_nullable()
628 FREE(nullable);
632 lr0()
634 set_derives();
635 set_nullable();
636 generate_states();