Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / byacc / dist / lr0.c
blobd75daeca3b466a5c632eda19a3d07f3153ee8cb8
1 /* $NetBSD$ */
2 /* Id: lr0.c,v 1.9 2009/10/27 09:20:39 tom Exp */
4 #include "defs.h"
6 #include <sys/cdefs.h>
7 __RCSID("$NetBSD: closure.c,v 1.8 2006/05/24 18:01:43 christos Exp $");
9 static core *new_state(int symbol);
10 static Value_t get_state(int symbol);
11 static void allocate_itemsets(void);
12 static void allocate_storage(void);
13 static void append_states(void);
14 static void free_storage(void);
15 static void generate_states(void);
16 static void initialize_states(void);
17 static void new_itemsets(void);
18 static void save_reductions(void);
19 static void save_shifts(void);
20 static void set_derives(void);
21 static void set_nullable(void);
23 int nstates;
24 core *first_state;
25 shifts *first_shift;
26 reductions *first_reduction;
28 static core **state_set;
29 static core *this_state;
30 static core *last_state;
31 static shifts *last_shift;
32 static reductions *last_reduction;
34 static int nshifts;
35 static short *shift_symbol;
37 static Value_t *redset;
38 static Value_t *shiftset;
40 static Value_t **kernel_base;
41 static Value_t **kernel_end;
42 static Value_t *kernel_items;
44 static void
45 allocate_itemsets(void)
47 short *itemp;
48 short *item_end;
49 int symbol;
50 int i;
51 int count;
52 int max;
53 short *symbol_count;
55 count = 0;
56 symbol_count = NEW2(nsyms, short);
58 item_end = ritem + nitems;
59 for (itemp = ritem; itemp < item_end; itemp++)
61 symbol = *itemp;
62 if (symbol >= 0)
64 count++;
65 symbol_count[symbol]++;
69 kernel_base = NEW2(nsyms, short *);
70 kernel_items = NEW2(count, short);
72 count = 0;
73 max = 0;
74 for (i = 0; i < nsyms; i++)
76 kernel_base[i] = kernel_items + count;
77 count += symbol_count[i];
78 if (max < symbol_count[i])
79 max = symbol_count[i];
82 shift_symbol = symbol_count;
83 kernel_end = NEW2(nsyms, short *);
86 static void
87 allocate_storage(void)
89 allocate_itemsets();
90 shiftset = NEW2(nsyms, short);
91 redset = NEW2(nrules + 1, short);
92 state_set = NEW2(nitems, core *);
95 static void
96 append_states(void)
98 int i;
99 int j;
100 Value_t symbol;
102 #ifdef TRACE
103 fprintf(stderr, "Entering append_states()\n");
104 #endif
105 for (i = 1; i < nshifts; i++)
107 symbol = shift_symbol[i];
108 j = i;
109 while (j > 0 && shift_symbol[j - 1] > symbol)
111 shift_symbol[j] = shift_symbol[j - 1];
112 j--;
114 shift_symbol[j] = symbol;
117 for (i = 0; i < nshifts; i++)
119 symbol = shift_symbol[i];
120 shiftset[i] = get_state(symbol);
124 static void
125 free_storage(void)
127 FREE(shift_symbol);
128 FREE(redset);
129 FREE(shiftset);
130 FREE(kernel_base);
131 FREE(kernel_end);
132 FREE(kernel_items);
133 FREE(state_set);
136 static void
137 generate_states(void)
139 allocate_storage();
140 itemset = NEW2(nitems, short);
141 ruleset = NEW2(WORDSIZE(nrules), unsigned);
142 set_first_derives();
143 initialize_states();
145 while (this_state)
147 closure(this_state->items, this_state->nitems);
148 save_reductions();
149 new_itemsets();
150 append_states();
152 if (nshifts > 0)
153 save_shifts();
155 this_state = this_state->next;
158 free_storage();
161 static Value_t
162 get_state(int symbol)
164 int key;
165 short *isp1;
166 short *isp2;
167 short *iend;
168 core *sp;
169 int found;
170 int n;
172 #ifdef TRACE
173 fprintf(stderr, "Entering get_state(%d)\n", symbol);
174 #endif
176 isp1 = kernel_base[symbol];
177 iend = kernel_end[symbol];
178 n = iend - isp1;
180 key = *isp1;
181 assert(0 <= key && key < nitems);
182 sp = state_set[key];
183 if (sp)
185 found = 0;
186 while (!found)
188 if (sp->nitems == n)
190 found = 1;
191 isp1 = kernel_base[symbol];
192 isp2 = sp->items;
194 while (found && isp1 < iend)
196 if (*isp1++ != *isp2++)
197 found = 0;
201 if (!found)
203 if (sp->link)
205 sp = sp->link;
207 else
209 sp = sp->link = new_state(symbol);
210 found = 1;
215 else
217 state_set[key] = sp = new_state(symbol);
220 return (sp->number);
223 static void
224 initialize_states(void)
226 unsigned i;
227 short *start_derives;
228 core *p;
230 start_derives = derives[start_symbol];
231 for (i = 0; start_derives[i] >= 0; ++i)
232 continue;
234 p = (core *)MALLOC(sizeof(core) + i * sizeof(short));
235 if (p == 0)
236 no_space();
238 p->next = 0;
239 p->link = 0;
240 p->number = 0;
241 p->accessing_symbol = 0;
242 p->nitems = (Value_t) i;
244 for (i = 0; start_derives[i] >= 0; ++i)
245 p->items[i] = rrhs[start_derives[i]];
247 first_state = last_state = this_state = p;
248 nstates = 1;
251 static void
252 new_itemsets(void)
254 Value_t i;
255 int shiftcount;
256 short *isp;
257 short *ksp;
258 Value_t symbol;
260 for (i = 0; i < nsyms; i++)
261 kernel_end[i] = 0;
263 shiftcount = 0;
264 isp = itemset;
265 while (isp < itemsetend)
267 i = *isp++;
268 symbol = ritem[i];
269 if (symbol > 0)
271 ksp = kernel_end[symbol];
272 if (!ksp)
274 shift_symbol[shiftcount++] = symbol;
275 ksp = kernel_base[symbol];
278 *ksp++ = (Value_t) (i + 1);
279 kernel_end[symbol] = ksp;
283 nshifts = shiftcount;
286 static core *
287 new_state(int symbol)
289 unsigned n;
290 core *p;
291 short *isp1;
292 short *isp2;
293 short *iend;
295 #ifdef TRACE
296 fprintf(stderr, "Entering new_state(%d)\n", symbol);
297 #endif
299 if (nstates >= MAXSHORT)
300 fatal("too many states");
302 isp1 = kernel_base[symbol];
303 iend = kernel_end[symbol];
304 n = (unsigned)(iend - isp1);
306 p = (core *)allocate((unsigned)(sizeof(core) + (n - 1) * sizeof(short)));
307 p->accessing_symbol = (Value_t) symbol;
308 p->number = (Value_t) nstates;
309 p->nitems = (Value_t) n;
311 isp2 = p->items;
312 while (isp1 < iend)
313 *isp2++ = *isp1++;
315 last_state->next = p;
316 last_state = p;
318 nstates++;
320 return (p);
323 /* show_cores is used for debugging */
325 void
326 show_cores(void)
328 core *p;
329 int i, j, k, n;
330 int itemno;
332 k = 0;
333 for (p = first_state; p; ++k, p = p->next)
335 if (k)
336 printf("\n");
337 printf("state %d, number = %d, accessing symbol = %s\n",
338 k, p->number, symbol_name[p->accessing_symbol]);
339 n = p->nitems;
340 for (i = 0; i < n; ++i)
342 itemno = p->items[i];
343 printf("%4d ", itemno);
344 j = itemno;
345 while (ritem[j] >= 0)
346 ++j;
347 printf("%s :", symbol_name[rlhs[-ritem[j]]]);
348 j = rrhs[-ritem[j]];
349 while (j < itemno)
350 printf(" %s", symbol_name[ritem[j++]]);
351 printf(" .");
352 while (ritem[j] >= 0)
353 printf(" %s", symbol_name[ritem[j++]]);
354 printf("\n");
355 fflush(stdout);
360 /* show_ritems is used for debugging */
362 void
363 show_ritems(void)
365 int i;
367 for (i = 0; i < nitems; ++i)
368 printf("ritem[%d] = %d\n", i, ritem[i]);
371 /* show_rrhs is used for debugging */
372 void
373 show_rrhs(void)
375 int i;
377 for (i = 0; i < nrules; ++i)
378 printf("rrhs[%d] = %d\n", i, rrhs[i]);
381 /* show_shifts is used for debugging */
383 void
384 show_shifts(void)
386 shifts *p;
387 int i, j, k;
389 k = 0;
390 for (p = first_shift; p; ++k, p = p->next)
392 if (k)
393 printf("\n");
394 printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
395 p->nshifts);
396 j = p->nshifts;
397 for (i = 0; i < j; ++i)
398 printf("\t%d\n", p->shift[i]);
402 static void
403 save_shifts(void)
405 shifts *p;
406 short *sp1;
407 short *sp2;
408 short *send;
410 p = (shifts *)allocate((unsigned)(sizeof(shifts) +
411 (unsigned)(nshifts - 1) * sizeof(short)));
413 p->number = this_state->number;
414 p->nshifts = (Value_t) nshifts;
416 sp1 = shiftset;
417 sp2 = p->shift;
418 send = shiftset + nshifts;
420 while (sp1 < send)
421 *sp2++ = *sp1++;
423 if (last_shift)
425 last_shift->next = p;
426 last_shift = p;
428 else
430 first_shift = p;
431 last_shift = p;
435 static void
436 save_reductions(void)
438 short *isp;
439 short *rp1;
440 short *rp2;
441 int item;
442 Value_t count;
443 reductions *p;
444 short *rend;
446 count = 0;
447 for (isp = itemset; isp < itemsetend; isp++)
449 item = ritem[*isp];
450 if (item < 0)
452 redset[count++] = (Value_t) - item;
456 if (count)
458 p = (reductions *)allocate((unsigned)(sizeof(reductions) +
459 (unsigned)(count - 1) *
460 sizeof(short)));
462 p->number = this_state->number;
463 p->nreds = count;
465 rp1 = redset;
466 rp2 = p->rules;
467 rend = rp1 + count;
469 while (rp1 < rend)
470 *rp2++ = *rp1++;
472 if (last_reduction)
474 last_reduction->next = p;
475 last_reduction = p;
477 else
479 first_reduction = p;
480 last_reduction = p;
485 static void
486 set_derives(void)
488 Value_t i, k;
489 int lhs;
490 short *rules;
492 derives = NEW2(nsyms, short *);
493 rules = NEW2(nvars + nrules, short);
495 k = 0;
496 for (lhs = start_symbol; lhs < nsyms; lhs++)
498 derives[lhs] = rules + k;
499 for (i = 0; i < nrules; i++)
501 if (rlhs[i] == lhs)
503 rules[k] = i;
504 k++;
507 rules[k] = -1;
508 k++;
511 #ifdef DEBUG
512 print_derives();
513 #endif
516 #ifdef DEBUG
517 void
518 print_derives(void)
520 int i;
521 short *sp;
523 printf("\nDERIVES\n\n");
525 for (i = start_symbol; i < nsyms; i++)
527 printf("%s derives ", symbol_name[i]);
528 for (sp = derives[i]; *sp >= 0; sp++)
530 printf(" %d", *sp);
532 putchar('\n');
535 putchar('\n');
537 #endif
539 static void
540 set_nullable(void)
542 int i, j;
543 int empty;
544 int done_flag;
546 nullable = MALLOC(nsyms);
547 if (nullable == 0)
548 no_space();
550 for (i = 0; i < nsyms; ++i)
551 nullable[i] = 0;
553 done_flag = 0;
554 while (!done_flag)
556 done_flag = 1;
557 for (i = 1; i < nitems; i++)
559 empty = 1;
560 while ((j = ritem[i]) >= 0)
562 if (!nullable[j])
563 empty = 0;
564 ++i;
566 if (empty)
568 j = rlhs[-j];
569 if (!nullable[j])
571 nullable[j] = 1;
572 done_flag = 0;
578 #ifdef DEBUG
579 for (i = 0; i < nsyms; i++)
581 if (nullable[i])
582 printf("%s is nullable\n", symbol_name[i]);
583 else
584 printf("%s is not nullable\n", symbol_name[i]);
586 #endif
589 void
590 lr0(void)
592 set_derives();
593 set_nullable();
594 generate_states();
597 #ifdef NO_LEAKS
598 void
599 lr0_leaks(void)
601 DO_FREE(derives[start_symbol]);
602 DO_FREE(derives);
603 DO_FREE(nullable);
605 #endif