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