No empty .Rs/.Re
[netbsd-mini2440.git] / usr.bin / yacc / lr0.c
blobeeff904cdbc206c57dce57afca3ee11f23647a5c
1 /* $NetBSD: lr0.c,v 1.9 2006/05/24 18:01:43 christos Exp $ */
3 /*
4 * Copyright (c) 1989 The Regents of the University of California.
5 * All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Robert Paul Corbett.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 #if defined(__RCSID) && !defined(lint)
37 #if 0
38 static char sccsid[] = "@(#)lr0.c 5.3 (Berkeley) 1/20/91";
39 #else
40 __RCSID("$NetBSD: lr0.c,v 1.9 2006/05/24 18:01:43 christos Exp $");
41 #endif
42 #endif /* not lint */
44 #include "defs.h"
46 extern short *itemset;
47 extern short *itemsetend;
48 extern unsigned *ruleset;
50 int nstates;
51 core *first_state;
52 shifts *first_shift;
53 reductions *first_reduction;
55 static int get_state(int);
56 static core *new_state(int);
58 static void allocate_itemsets(void);
59 static void allocate_storage(void);
60 static void append_states(void);
61 static void free_storage(void);
62 static void generate_states(void);
63 static void initialize_states(void);
64 static void new_itemsets(void);
65 #ifdef DEBUG
66 static void show_cores(void);
67 static void show_ritems(void);
68 static void show_rrhs(void);
69 static void show_shifts(void);
70 #endif
71 static void save_shifts(void);
72 static void save_reductions(void);
73 static void set_derives(void);
74 static void set_nullable(void);
75 #ifdef DEBUG
76 static void print_derives(void);
77 static void free_derives(void);
78 static void free_nullable(void);
79 #endif
81 static core **state_set;
82 static core *this_state;
83 static core *last_state;
84 static shifts *last_shift;
85 static reductions *last_reduction;
87 static int nshifts;
88 static short *shift_symbol;
90 static short *redset;
91 static short *shiftset;
93 static short **kernel_base;
94 static short **kernel_end;
95 static short *kernel_items;
97 static void
98 allocate_itemsets(void)
100 short *itemp;
101 short *item_end;
102 int symbol;
103 int i;
104 int count;
105 int max;
106 short *symbol_count;
108 count = 0;
109 symbol_count = NEW2(nsyms, short);
111 item_end = ritem + nitems;
112 for (itemp = ritem; itemp < item_end; itemp++)
114 symbol = *itemp;
115 if (symbol >= 0)
117 count++;
118 symbol_count[symbol]++;
122 kernel_base = NEW2(nsyms, short *);
123 kernel_items = NEW2(count, short);
125 count = 0;
126 max = 0;
127 for (i = 0; i < nsyms; i++)
129 kernel_base[i] = kernel_items + count;
130 count += symbol_count[i];
131 if (max < symbol_count[i])
132 max = symbol_count[i];
135 shift_symbol = symbol_count;
136 kernel_end = NEW2(nsyms, short *);
139 static void
140 allocate_storage(void)
142 allocate_itemsets();
143 shiftset = NEW2(nsyms, short);
144 redset = NEW2(nrules + 1, short);
145 state_set = NEW2(nitems, core *);
148 static void
149 append_states(void)
151 int i;
152 int j;
153 int symbol;
155 #ifdef TRACE
156 fprintf(stderr, "Entering append_states()\n");
157 #endif
158 for (i = 1; i < nshifts; i++)
160 symbol = shift_symbol[i];
161 j = i;
162 while (j > 0 && shift_symbol[j - 1] > symbol)
164 shift_symbol[j] = shift_symbol[j - 1];
165 j--;
167 shift_symbol[j] = symbol;
170 for (i = 0; i < nshifts; i++)
172 symbol = shift_symbol[i];
173 shiftset[i] = get_state(symbol);
177 static void
178 free_storage(void)
180 FREE(shift_symbol);
181 FREE(redset);
182 FREE(shiftset);
183 FREE(kernel_base);
184 FREE(kernel_end);
185 FREE(kernel_items);
186 FREE(state_set);
190 static void
191 generate_states(void)
193 allocate_storage();
194 itemset = NEW2(nitems, short);
195 ruleset = NEW2(WORDSIZE(nrules), unsigned);
196 set_first_derives();
197 initialize_states();
199 while (this_state)
201 closure(this_state->items, this_state->nitems);
202 save_reductions();
203 new_itemsets();
204 append_states();
206 if (nshifts > 0)
207 save_shifts();
209 this_state = this_state->next;
212 finalize_closure();
213 free_storage();
218 static int
219 get_state(int symbol)
221 int key;
222 short *isp1;
223 short *isp2;
224 short *iend;
225 core *sp;
226 int found;
227 int n;
229 #ifdef TRACE
230 fprintf(stderr, "Entering get_state(%d)\n", symbol);
231 #endif
233 isp1 = kernel_base[symbol];
234 iend = kernel_end[symbol];
235 n = iend - isp1;
237 key = *isp1;
238 assert(0 <= key && key < nitems);
239 sp = state_set[key];
240 if (sp)
242 found = 0;
243 while (!found)
245 if (sp->nitems == n)
247 found = 1;
248 isp1 = kernel_base[symbol];
249 isp2 = sp->items;
251 while (found && isp1 < iend)
253 if (*isp1++ != *isp2++)
254 found = 0;
258 if (!found)
260 if (sp->link)
262 sp = sp->link;
264 else
266 sp = sp->link = new_state(symbol);
267 found = 1;
272 else
274 state_set[key] = sp = new_state(symbol);
277 return (sp->number);
281 static void
282 initialize_states(void)
284 int i;
285 short *start_derives;
286 core *p;
288 start_derives = derives[start_symbol];
289 for (i = 0; start_derives[i] >= 0; ++i)
290 continue;
292 p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
293 if (p == 0) no_space();
295 p->next = 0;
296 p->link = 0;
297 p->number = 0;
298 p->accessing_symbol = 0;
299 p->nitems = i;
301 for (i = 0; start_derives[i] >= 0; ++i)
302 p->items[i] = rrhs[start_derives[i]];
304 first_state = last_state = this_state = p;
305 nstates = 1;
309 static void
310 new_itemsets(void)
312 int i;
313 int shiftcount;
314 short *isp;
315 short *ksp;
316 int symbol;
318 for (i = 0; i < nsyms; i++)
319 kernel_end[i] = 0;
321 shiftcount = 0;
322 isp = itemset;
323 while (isp < itemsetend)
325 i = *isp++;
326 symbol = ritem[i];
327 if (symbol > 0)
329 ksp = kernel_end[symbol];
330 if (!ksp)
332 shift_symbol[shiftcount++] = symbol;
333 ksp = kernel_base[symbol];
336 *ksp++ = i + 1;
337 kernel_end[symbol] = ksp;
341 nshifts = shiftcount;
346 static core *
347 new_state(int symbol)
349 int n;
350 core *p;
351 short *isp1;
352 short *isp2;
353 short *iend;
355 #ifdef TRACE
356 fprintf(stderr, "Entering new_state(%d)\n", symbol);
357 #endif
359 if (nstates >= MAXSHORT)
360 fatal("too many states");
362 isp1 = kernel_base[symbol];
363 iend = kernel_end[symbol];
364 n = iend - isp1;
366 p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
367 p->accessing_symbol = symbol;
368 p->number = nstates;
369 p->nitems = n;
371 isp2 = p->items;
372 while (isp1 < iend)
373 *isp2++ = *isp1++;
375 last_state->next = p;
376 last_state = p;
378 nstates++;
380 return (p);
383 #ifdef DEBUG
384 /* show_cores is used for debugging */
385 static void
386 show_cores(void)
388 core *p;
389 int i, j, k, n;
390 int itemno;
392 k = 0;
393 for (p = first_state; p; ++k, p = p->next)
395 if (k) printf("\n");
396 printf("state %d, number = %d, accessing symbol = %s\n",
397 k, p->number, symbol_name[p->accessing_symbol]);
398 n = p->nitems;
399 for (i = 0; i < n; ++i)
401 itemno = p->items[i];
402 printf("%4d ", itemno);
403 j = itemno;
404 while (ritem[j] >= 0) ++j;
405 printf("%s :", symbol_name[rlhs[-ritem[j]]]);
406 j = rrhs[-ritem[j]];
407 while (j < itemno)
408 printf(" %s", symbol_name[ritem[j++]]);
409 printf(" .");
410 while (ritem[j] >= 0)
411 printf(" %s", symbol_name[ritem[j++]]);
412 printf("\n");
413 fflush(stdout);
419 /* show_ritems is used for debugging */
420 static void
421 show_ritems(void)
423 int i;
425 for (i = 0; i < nitems; ++i)
426 printf("ritem[%d] = %d\n", i, ritem[i]);
430 /* show_rrhs is used for debugging */
431 static void
432 show_rrhs(void)
434 int i;
436 for (i = 0; i < nrules; ++i)
437 printf("rrhs[%d] = %d\n", i, rrhs[i]);
441 /* show_shifts is used for debugging */
442 static void
443 show_shifts(void)
445 shifts *p;
446 int i, j, k;
448 k = 0;
449 for (p = first_shift; p; ++k, p = p->next)
451 if (k) printf("\n");
452 printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
453 p->nshifts);
454 j = p->nshifts;
455 for (i = 0; i < j; ++i)
456 printf("\t%d\n", p->shift[i]);
459 #endif
462 static void
463 save_shifts(void)
465 shifts *p;
466 short *sp1;
467 short *sp2;
468 short *send;
470 p = (shifts *) allocate((unsigned) (sizeof(shifts) +
471 (nshifts - 1) * sizeof(short)));
473 p->number = this_state->number;
474 p->nshifts = nshifts;
476 sp1 = shiftset;
477 sp2 = p->shift;
478 send = shiftset + nshifts;
480 while (sp1 < send)
481 *sp2++ = *sp1++;
483 if (last_shift)
485 last_shift->next = p;
486 last_shift = p;
488 else
490 first_shift = p;
491 last_shift = p;
496 static void
497 save_reductions(void)
499 short *isp;
500 short *rp1;
501 short *rp2;
502 int item;
503 int count;
504 reductions *p;
505 short *rend;
507 count = 0;
508 for (isp = itemset; isp < itemsetend; isp++)
510 item = ritem[*isp];
511 if (item < 0)
513 redset[count++] = -item;
517 if (count)
519 p = (reductions *) allocate((unsigned) (sizeof(reductions) +
520 (count - 1) * sizeof(short)));
522 p->number = this_state->number;
523 p->nreds = count;
525 rp1 = redset;
526 rp2 = p->rules;
527 rend = rp1 + count;
529 while (rp1 < rend)
530 *rp2++ = *rp1++;
532 if (last_reduction)
534 last_reduction->next = p;
535 last_reduction = p;
537 else
539 first_reduction = p;
540 last_reduction = p;
546 static void
547 set_derives(void)
549 int i, k;
550 int lhs;
551 short *rules;
553 derives = NEW2(nsyms, short *);
554 if (start_symbol >= nsyms)
555 return;
557 rules = NEW2(nvars + nrules, short);
559 k = 0;
560 for (lhs = start_symbol; lhs < nsyms; lhs++)
562 derives[lhs] = rules + k;
563 for (i = 0; i < nrules; i++)
565 if (rlhs[i] == lhs)
567 rules[k] = i;
568 k++;
571 rules[k] = -1;
572 k++;
575 #ifdef DEBUG
576 print_derives();
577 #endif
580 #ifdef DEBUG
581 static void
582 free_derives(void)
584 FREE(derives[start_symbol]);
585 FREE(derives);
587 #endif
589 #ifdef DEBUG
590 static void
591 print_derives(void)
593 int i;
594 short *sp;
596 printf("\nDERIVES\n\n");
598 for (i = start_symbol; i < nsyms; i++)
600 printf("%s derives ", symbol_name[i]);
601 for (sp = derives[i]; *sp >= 0; sp++)
603 printf(" %d", *sp);
605 putchar('\n');
608 putchar('\n');
610 #endif
613 static void
614 set_nullable(void)
616 int i, j;
617 int empty;
618 int isdone;
620 nullable = MALLOC(nsyms);
621 if (nullable == 0) no_space();
623 for (i = 0; i < nsyms; ++i)
624 nullable[i] = 0;
626 isdone = 0;
627 while (!isdone)
629 isdone = 1;
630 for (i = 1; i < nitems; i++)
632 empty = 1;
633 while ((j = ritem[i]) >= 0)
635 if (!nullable[j])
636 empty = 0;
637 ++i;
639 if (empty)
641 j = rlhs[-j];
642 if (!nullable[j])
644 nullable[j] = 1;
645 isdone = 0;
651 #ifdef DEBUG
652 for (i = 0; i < nsyms; i++)
654 if (nullable[i])
655 printf("%s is nullable\n", symbol_name[i]);
656 else
657 printf("%s is not nullable\n", symbol_name[i]);
659 #endif
663 #ifdef DEBUG
664 static void
665 free_nullable(void)
667 FREE(nullable);
669 #endif
672 void
673 lr0(void)
675 set_derives();
676 set_nullable();
677 generate_states();