Imported Upstream version 20200910
[platform/upstream/byacc.git] / lr0.c
1 /* $Id: lr0.c,v 1.20 2020/09/10 17:30:37 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 i;
48     int count;
49     int max;
50     Value_t *symbol_count;
51
52     count = 0;
53     symbol_count = NEW2(nsyms, Value_t);
54
55     item_end = ritem + nitems;
56     for (itemp = ritem; itemp < item_end; itemp++)
57     {
58         int symbol = *itemp;
59
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     Value_t symbol;
98
99 #ifdef  TRACE
100     fprintf(stderr, "Entering append_states()\n");
101 #endif
102     for (i = 1; i < nshifts; i++)
103     {
104         int j = i;
105
106         symbol = shift_symbol[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 *iend;
165     core *sp;
166     int n;
167
168 #ifdef  TRACE
169     fprintf(stderr, "Entering get_state(%d)\n", symbol);
170 #endif
171
172     isp1 = kernel_base[symbol];
173     iend = kernel_end[symbol];
174     n = (int)(iend - isp1);
175
176     key = *isp1;
177     assert(0 <= key && key < nitems);
178     sp = state_set[key];
179     if (sp)
180     {
181         int found = 0;
182
183         while (!found)
184         {
185             if (sp->nitems == n)
186             {
187                 Value_t *isp2;
188
189                 found = 1;
190                 isp1 = kernel_base[symbol];
191                 isp2 = sp->items;
192
193                 while (found && isp1 < iend)
194                 {
195                     if (*isp1++ != *isp2++)
196                         found = 0;
197                 }
198             }
199
200             if (!found)
201             {
202                 if (sp->link)
203                 {
204                     sp = sp->link;
205                 }
206                 else
207                 {
208                     sp = sp->link = new_state(symbol);
209                     found = 1;
210                 }
211             }
212         }
213     }
214     else
215     {
216         state_set[key] = sp = new_state(symbol);
217     }
218
219     return (sp->number);
220 }
221
222 static void
223 initialize_states(void)
224 {
225     unsigned i;
226     Value_t *start_derives;
227     core *p;
228
229     start_derives = derives[start_symbol];
230     for (i = 0; start_derives[i] >= 0; ++i)
231         continue;
232
233     p = (core *)MALLOC(sizeof(core) + i * sizeof(Value_t));
234     NO_SPACE(p);
235
236     p->next = 0;
237     p->link = 0;
238     p->number = 0;
239     p->accessing_symbol = 0;
240     p->nitems = (Value_t)i;
241
242     for (i = 0; start_derives[i] >= 0; ++i)
243         p->items[i] = rrhs[start_derives[i]];
244
245     first_state = last_state = this_state = p;
246     nstates = 1;
247 }
248
249 static void
250 new_itemsets(void)
251 {
252     Value_t i;
253     int shiftcount;
254     Value_t *isp;
255     Value_t *ksp;
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         int j = *isp++;
265         Value_t symbol = ritem[j];
266
267         if (symbol > 0)
268         {
269             ksp = kernel_end[symbol];
270             if (!ksp)
271             {
272                 shift_symbol[shiftcount++] = symbol;
273                 ksp = kernel_base[symbol];
274             }
275
276             *ksp++ = (Value_t)(j + 1);
277             kernel_end[symbol] = ksp;
278         }
279     }
280
281     nshifts = shiftcount;
282 }
283
284 static core *
285 new_state(int symbol)
286 {
287     unsigned n;
288     core *p;
289     Value_t *isp1;
290     Value_t *isp2;
291     Value_t *iend;
292
293 #ifdef  TRACE
294     fprintf(stderr, "Entering new_state(%d)\n", symbol);
295 #endif
296
297     if (nstates >= MAXYYINT)
298         fatal("too many states");
299
300     isp1 = kernel_base[symbol];
301     iend = kernel_end[symbol];
302     n = (unsigned)(iend - isp1);
303
304     p = (core *)allocate((sizeof(core) + (n - 1) * sizeof(Value_t)));
305     p->accessing_symbol = (Value_t)symbol;
306     p->number = (Value_t)nstates;
307     p->nitems = (Value_t)n;
308
309     isp2 = p->items;
310     while (isp1 < iend)
311         *isp2++ = *isp1++;
312
313     last_state->next = p;
314     last_state = p;
315
316     nstates++;
317
318     return (p);
319 }
320
321 /* show_cores is used for debugging */
322 #ifdef DEBUG
323 void
324 show_cores(void)
325 {
326     core *p;
327     int i, j, k, n;
328     int itemno;
329
330     k = 0;
331     for (p = first_state; p; ++k, p = p->next)
332     {
333         if (k)
334             printf("\n");
335         printf("state %d, number = %d, accessing symbol = %s\n",
336                k, p->number, symbol_name[p->accessing_symbol]);
337         n = p->nitems;
338         for (i = 0; i < n; ++i)
339         {
340             itemno = p->items[i];
341             printf("%4d  ", itemno);
342             j = itemno;
343             while (ritem[j] >= 0)
344                 ++j;
345             printf("%s :", symbol_name[rlhs[-ritem[j]]]);
346             j = rrhs[-ritem[j]];
347             while (j < itemno)
348                 printf(" %s", symbol_name[ritem[j++]]);
349             printf(" .");
350             while (ritem[j] >= 0)
351                 printf(" %s", symbol_name[ritem[j++]]);
352             printf("\n");
353             fflush(stdout);
354         }
355     }
356 }
357
358 /* show_ritems is used for debugging */
359
360 void
361 show_ritems(void)
362 {
363     int i;
364
365     for (i = 0; i < nitems; ++i)
366         printf("ritem[%d] = %d\n", i, ritem[i]);
367 }
368
369 /* show_rrhs is used for debugging */
370 void
371 show_rrhs(void)
372 {
373     int i;
374
375     for (i = 0; i < nrules; ++i)
376         printf("rrhs[%d] = %d\n", i, rrhs[i]);
377 }
378
379 /* show_shifts is used for debugging */
380
381 void
382 show_shifts(void)
383 {
384     shifts *p;
385     int i, j, k;
386
387     k = 0;
388     for (p = first_shift; p; ++k, p = p->next)
389     {
390         if (k)
391             printf("\n");
392         printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
393                p->nshifts);
394         j = p->nshifts;
395         for (i = 0; i < j; ++i)
396             printf("\t%d\n", p->shift[i]);
397     }
398 }
399 #endif
400
401 static void
402 save_shifts(void)
403 {
404     shifts *p;
405     Value_t *sp1;
406     Value_t *sp2;
407     Value_t *send;
408
409     p = (shifts *)allocate((sizeof(shifts) +
410                               (unsigned)(nshifts - 1) * sizeof(Value_t)));
411
412     p->number = this_state->number;
413     p->nshifts = (Value_t)nshifts;
414
415     sp1 = shiftset;
416     sp2 = p->shift;
417     send = shiftset + nshifts;
418
419     while (sp1 < send)
420         *sp2++ = *sp1++;
421
422     if (last_shift)
423     {
424         last_shift->next = p;
425         last_shift = p;
426     }
427     else
428     {
429         first_shift = p;
430         last_shift = p;
431     }
432 }
433
434 static void
435 save_reductions(void)
436 {
437     Value_t *isp;
438     Value_t *rp1;
439     Value_t count;
440     reductions *p;
441
442     count = 0;
443     for (isp = itemset; isp < itemsetend; isp++)
444     {
445         int item = ritem[*isp];
446
447         if (item < 0)
448         {
449             redset[count++] = (Value_t)-item;
450         }
451     }
452
453     if (count)
454     {
455         Value_t *rp2;
456         Value_t *rend;
457
458         p = (reductions *)allocate((sizeof(reductions) +
459                                       (unsigned)(count - 1) *
460                                     sizeof(Value_t)));
461
462         p->number = this_state->number;
463         p->nreds = count;
464
465         rp1 = redset;
466         rp2 = p->rules;
467         rend = rp1 + count;
468
469         while (rp1 < rend)
470             *rp2++ = *rp1++;
471
472         if (last_reduction)
473         {
474             last_reduction->next = p;
475             last_reduction = p;
476         }
477         else
478         {
479             first_reduction = p;
480             last_reduction = p;
481         }
482     }
483 }
484
485 static void
486 set_derives(void)
487 {
488     Value_t i, k;
489     int lhs;
490
491     derives = NEW2(nsyms, Value_t *);
492     rules = NEW2(nvars + nrules, Value_t);
493
494     k = 0;
495     for (lhs = start_symbol; lhs < nsyms; lhs++)
496     {
497         derives[lhs] = rules + k;
498         for (i = 0; i < nrules; i++)
499         {
500             if (rlhs[i] == lhs)
501             {
502                 rules[k] = i;
503                 k++;
504             }
505         }
506         rules[k] = -1;
507         k++;
508     }
509
510 #ifdef  DEBUG
511     print_derives();
512 #endif
513 }
514
515 #ifdef  DEBUG
516 void
517 print_derives(void)
518 {
519     int i;
520     Value_t *sp;
521
522     printf("\nDERIVES\n\n");
523
524     for (i = start_symbol; i < nsyms; i++)
525     {
526         printf("%s derives ", symbol_name[i]);
527         for (sp = derives[i]; *sp >= 0; sp++)
528         {
529             printf("  %d", *sp);
530         }
531         putchar('\n');
532     }
533
534     putchar('\n');
535 }
536 #endif
537
538 static void
539 set_nullable(void)
540 {
541     int i, j;
542     int empty;
543     int done_flag;
544
545     nullable = TMALLOC(char, nsyms);
546     NO_SPACE(nullable);
547
548     for (i = 0; i < nsyms; ++i)
549         nullable[i] = 0;
550
551     done_flag = 0;
552     while (!done_flag)
553     {
554         done_flag = 1;
555         for (i = 1; i < nitems; i++)
556         {
557             empty = 1;
558             while ((j = ritem[i]) >= 0)
559             {
560                 if (!nullable[j])
561                     empty = 0;
562                 ++i;
563             }
564             if (empty)
565             {
566                 j = rlhs[-j];
567                 if (!nullable[j])
568                 {
569                     nullable[j] = 1;
570                     done_flag = 0;
571                 }
572             }
573         }
574     }
575
576 #ifdef DEBUG
577     for (i = 0; i < nsyms; i++)
578     {
579         if (nullable[i])
580             printf("%s is nullable\n", symbol_name[i]);
581         else
582             printf("%s is not nullable\n", symbol_name[i]);
583     }
584 #endif
585 }
586
587 void
588 lr0(void)
589 {
590     set_derives();
591     set_nullable();
592     generate_states();
593 }
594
595 #ifdef NO_LEAKS
596 void
597 lr0_leaks(void)
598 {
599     if (derives)
600     {
601         if (derives[start_symbol] != rules)
602         {
603             DO_FREE(derives[start_symbol]);
604         }
605         DO_FREE(derives);
606         DO_FREE(rules);
607     }
608     DO_FREE(nullable);
609 }
610 #endif