|
|
1.1 root 1: /* Compute look-ahead criteria for bison,
2: Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
3:
4: This file is part of Bison, the GNU Compiler Compiler.
5:
6: Bison is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: Bison is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with Bison; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20:
21: /* Compute how to make the finite state machine deterministic;
22: find which rules need lookahead in each state, and which lookahead tokens they accept.
23:
24: lalr(), the entry point, builds these data structures:
25:
26: goto_map, from_state and to_state
27: record each shift transition which accepts a variable (a nonterminal).
28: ngotos is the number of such transitions.
29: from_state[t] is the state number which a transition leads from
30: and to_state[t] is the state number it leads to.
31: All the transitions that accept a particular variable are grouped together and
32: goto_map[i - ntokens] is the index in from_state and to_state of the first of them.
33:
34: consistent[s] is nonzero if no lookahead is needed to decide what to do in state s.
35:
36: LAruleno is a vector which records the rules that need lookahead in various states.
37: The elements of LAruleno that apply to state s are those from
38: lookaheads[s] through lookaheads[s+1]-1.
39: Each element of LAruleno is a rule number.
40:
41: If lr is the length of LAruleno, then a number from 0 to lr-1
42: can specify both a rule and a state where the rule might be applied.
43:
44: LA is a lr by ntokens matrix of bits.
45: LA[l, i] is 1 if the rule LAruleno[l] is applicable in the appropriate state
46: when the next token is symbol i.
47: If LA[l, i] and LA[l, j] are both 1 for i != j, it is a conflict.
48: */
49:
50: #include <stdio.h>
51: #include "system.h"
52: #include "machine.h"
53: #include "types.h"
54: #include "state.h"
55: #include "new.h"
56: #include "gram.h"
57:
58:
59: extern short **derives;
60: extern char *nullable;
61:
62:
63: int tokensetsize;
64: short *lookaheads;
65: short *LAruleno;
66: unsigned *LA;
67: short *accessing_symbol;
68: char *consistent;
69: core **state_table;
70: shifts **shift_table;
71: reductions **reduction_table;
72: short *goto_map;
73: short *from_state;
74: short *to_state;
75:
76: short **transpose();
77: void set_state_table();
78: void set_accessing_symbol();
79: void set_shift_table();
80: void set_reduction_table();
81: void set_maxrhs();
82: void initialize_LA();
83: void set_goto_map();
84: void initialize_F();
85: void build_relations();
86: void add_lookback_edge();
87: void compute_FOLLOWS();
88: void compute_lookaheads();
89: void digraph();
90: void traverse();
91:
92: extern void toomany();
93: extern void berror();
94:
95: static int infinity;
96: static int maxrhs;
97: static int ngotos;
98: static unsigned *F;
99: static short **includes;
100: static shorts **lookback;
101: static short **R;
102: static short *INDEX;
103: static short *VERTICES;
104: static int top;
105:
106:
107: void
108: lalr()
109: {
110: tokensetsize = WORDSIZE(ntokens);
111:
112: set_state_table();
113: set_accessing_symbol();
114: set_shift_table();
115: set_reduction_table();
116: set_maxrhs();
117: initialize_LA();
118: set_goto_map();
119: initialize_F();
120: build_relations();
121: compute_FOLLOWS();
122: compute_lookaheads();
123: }
124:
125:
126: void
127: set_state_table()
128: {
129: register core *sp;
130:
131: state_table = NEW2(nstates, core *);
132:
133: for (sp = first_state; sp; sp = sp->next)
134: state_table[sp->number] = sp;
135: }
136:
137:
138: void
139: set_accessing_symbol()
140: {
141: register core *sp;
142:
143: accessing_symbol = NEW2(nstates, short);
144:
145: for (sp = first_state; sp; sp = sp->next)
146: accessing_symbol[sp->number] = sp->accessing_symbol;
147: }
148:
149:
150: void
151: set_shift_table()
152: {
153: register shifts *sp;
154:
155: shift_table = NEW2(nstates, shifts *);
156:
157: for (sp = first_shift; sp; sp = sp->next)
158: shift_table[sp->number] = sp;
159: }
160:
161:
162: void
163: set_reduction_table()
164: {
165: register reductions *rp;
166:
167: reduction_table = NEW2(nstates, reductions *);
168:
169: for (rp = first_reduction; rp; rp = rp->next)
170: reduction_table[rp->number] = rp;
171: }
172:
173:
174: void
175: set_maxrhs()
176: {
177: register short *itemp;
178: register int length;
179: register int max;
180:
181: length = 0;
182: max = 0;
183: for (itemp = ritem; *itemp; itemp++)
184: {
185: if (*itemp > 0)
186: {
187: length++;
188: }
189: else
190: {
191: if (length > max) max = length;
192: length = 0;
193: }
194: }
195:
196: maxrhs = max;
197: }
198:
199:
200: void
201: initialize_LA()
202: {
203: register int i;
204: register int j;
205: register int count;
206: register reductions *rp;
207: register shifts *sp;
208: register short *np;
209:
210: consistent = NEW2(nstates, char);
211: lookaheads = NEW2(nstates + 1, short);
212:
213: count = 0;
214: for (i = 0; i < nstates; i++)
215: {
216: register int k;
217:
218: lookaheads[i] = count;
219:
220: rp = reduction_table[i];
221: sp = shift_table[i];
222: if (rp && (rp->nreds > 1
223: || (sp && ! ISVAR(accessing_symbol[sp->shifts[0]]))))
224: count += rp->nreds;
225: else
226: consistent[i] = 1;
227:
228: if (sp)
229: for (k = 0; k < sp->nshifts; k++)
230: {
231: if (accessing_symbol[sp->shifts[k]] == error_token_number)
232: {
233: consistent[i] = 0;
234: break;
235: }
236: }
237: }
238:
239: lookaheads[nstates] = count;
240:
241: if (count == 0)
242: {
243: LA = NEW2(1 * tokensetsize, unsigned);
244: LAruleno = NEW2(1, short);
245: lookback = NEW2(1, shorts *);
246: }
247: else
248: {
249: LA = NEW2(count * tokensetsize, unsigned);
250: LAruleno = NEW2(count, short);
251: lookback = NEW2(count, shorts *);
252: }
253:
254: np = LAruleno;
255: for (i = 0; i < nstates; i++)
256: {
257: if (!consistent[i])
258: {
259: if (rp = reduction_table[i])
260: for (j = 0; j < rp->nreds; j++)
261: *np++ = rp->rules[j];
262: }
263: }
264: }
265:
266:
267: void
268: set_goto_map()
269: {
270: register shifts *sp;
271: register int i;
272: register int symbol;
273: register int k;
274: register short *temp_map;
275: register int state2;
276: register int state1;
277:
278: goto_map = NEW2(nvars + 1, short) - ntokens;
279: temp_map = NEW2(nvars + 1, short) - ntokens;
280:
281: ngotos = 0;
282: for (sp = first_shift; sp; sp = sp->next)
283: {
284: for (i = sp->nshifts - 1; i >= 0; i--)
285: {
286: symbol = accessing_symbol[sp->shifts[i]];
287:
288: if (ISTOKEN(symbol)) break;
289:
290: if (ngotos == MAXSHORT)
291: toomany("gotos");
292:
293: ngotos++;
294: goto_map[symbol]++;
295: }
296: }
297:
298: k = 0;
299: for (i = ntokens; i < nsyms; i++)
300: {
301: temp_map[i] = k;
302: k += goto_map[i];
303: }
304:
305: for (i = ntokens; i < nsyms; i++)
306: goto_map[i] = temp_map[i];
307:
308: goto_map[nsyms] = ngotos;
309: temp_map[nsyms] = ngotos;
310:
311: from_state = NEW2(ngotos, short);
312: to_state = NEW2(ngotos, short);
313:
314: for (sp = first_shift; sp; sp = sp->next)
315: {
316: state1 = sp->number;
317: for (i = sp->nshifts - 1; i >= 0; i--)
318: {
319: state2 = sp->shifts[i];
320: symbol = accessing_symbol[state2];
321:
322: if (ISTOKEN(symbol)) break;
323:
324: k = temp_map[symbol]++;
325: from_state[k] = state1;
326: to_state[k] = state2;
327: }
328: }
329:
330: FREE(temp_map + ntokens);
331: }
332:
333:
334:
335: /* Map_goto maps a state/symbol pair into its numeric representation. */
336:
337: int
338: map_goto(state, symbol)
339: int state;
340: int symbol;
341: {
342: register int high;
343: register int low;
344: register int middle;
345: register int s;
346:
347: low = goto_map[symbol];
348: high = goto_map[symbol + 1] - 1;
349:
350: while (low <= high)
351: {
352: middle = (low + high) / 2;
353: s = from_state[middle];
354: if (s == state)
355: return (middle);
356: else if (s < state)
357: low = middle + 1;
358: else
359: high = middle - 1;
360: }
361:
362: berror("map_goto");
363: /* NOTREACHED */
364: return 0;
365: }
366:
367:
368: void
369: initialize_F()
370: {
371: register int i;
372: register int j;
373: register int k;
374: register shifts *sp;
375: register short *edge;
376: register unsigned *rowp;
377: register short *rp;
378: register short **reads;
379: register int nedges;
380: register int stateno;
381: register int symbol;
382: register int nwords;
383:
384: nwords = ngotos * tokensetsize;
385: F = NEW2(nwords, unsigned);
386:
387: reads = NEW2(ngotos, short *);
388: edge = NEW2(ngotos + 1, short);
389: nedges = 0;
390:
391: rowp = F;
392: for (i = 0; i < ngotos; i++)
393: {
394: stateno = to_state[i];
395: sp = shift_table[stateno];
396:
397: if (sp)
398: {
399: k = sp->nshifts;
400:
401: for (j = 0; j < k; j++)
402: {
403: symbol = accessing_symbol[sp->shifts[j]];
404: if (ISVAR(symbol))
405: break;
406: SETBIT(rowp, symbol);
407: }
408:
409: for (; j < k; j++)
410: {
411: symbol = accessing_symbol[sp->shifts[j]];
412: if (nullable[symbol])
413: edge[nedges++] = map_goto(stateno, symbol);
414: }
415:
416: if (nedges)
417: {
418: reads[i] = rp = NEW2(nedges + 1, short);
419:
420: for (j = 0; j < nedges; j++)
421: rp[j] = edge[j];
422:
423: rp[nedges] = -1;
424: nedges = 0;
425: }
426: }
427:
428: rowp += tokensetsize;
429: }
430:
431: digraph(reads);
432:
433: for (i = 0; i < ngotos; i++)
434: {
435: if (reads[i])
436: FREE(reads[i]);
437: }
438:
439: FREE(reads);
440: FREE(edge);
441: }
442:
443:
444: void
445: build_relations()
446: {
447: register int i;
448: register int j;
449: register int k;
450: register short *rulep;
451: register short *rp;
452: register shifts *sp;
453: register int length;
454: register int nedges;
455: register int done;
456: register int state1;
457: register int stateno;
458: register int symbol1;
459: register int symbol2;
460: register short *shortp;
461: register short *edge;
462: register short *states;
463: register short **new_includes;
464:
465: includes = NEW2(ngotos, short *);
466: edge = NEW2(ngotos + 1, short);
467: states = NEW2(maxrhs + 1, short);
468:
469: for (i = 0; i < ngotos; i++)
470: {
471: nedges = 0;
472: state1 = from_state[i];
473: symbol1 = accessing_symbol[to_state[i]];
474:
475: for (rulep = derives[symbol1]; *rulep > 0; rulep++)
476: {
477: length = 1;
478: states[0] = state1;
479: stateno = state1;
480:
481: for (rp = ritem + rrhs[*rulep]; *rp > 0; rp++)
482: {
483: symbol2 = *rp;
484: sp = shift_table[stateno];
485: k = sp->nshifts;
486:
487: for (j = 0; j < k; j++)
488: {
489: stateno = sp->shifts[j];
490: if (accessing_symbol[stateno] == symbol2) break;
491: }
492:
493: states[length++] = stateno;
494: }
495:
496: if (!consistent[stateno])
497: add_lookback_edge(stateno, *rulep, i);
498:
499: length--;
500: done = 0;
501: while (!done)
502: {
503: done = 1;
504: rp--;
505: /* JF added rp>=ritem && I hope to god its right! */
506: if (rp>=ritem && ISVAR(*rp))
507: {
508: stateno = states[--length];
509: edge[nedges++] = map_goto(stateno, *rp);
510: if (nullable[*rp]) done = 0;
511: }
512: }
513: }
514:
515: if (nedges)
516: {
517: includes[i] = shortp = NEW2(nedges + 1, short);
518: for (j = 0; j < nedges; j++)
519: shortp[j] = edge[j];
520: shortp[nedges] = -1;
521: }
522: }
523:
524: new_includes = transpose(includes, ngotos);
525:
526: for (i = 0; i < ngotos; i++)
527: if (includes[i])
528: FREE(includes[i]);
529:
530: FREE(includes);
531:
532: includes = new_includes;
533:
534: FREE(edge);
535: FREE(states);
536: }
537:
538:
539: void
540: add_lookback_edge(stateno, ruleno, gotono)
541: int stateno;
542: int ruleno;
543: int gotono;
544: {
545: register int i;
546: register int k;
547: register int found;
548: register shorts *sp;
549:
550: i = lookaheads[stateno];
551: k = lookaheads[stateno + 1];
552: found = 0;
553: while (!found && i < k)
554: {
555: if (LAruleno[i] == ruleno)
556: found = 1;
557: else
558: i++;
559: }
560:
561: if (found == 0)
562: berror("add_lookback_edge");
563:
564: sp = NEW(shorts);
565: sp->next = lookback[i];
566: sp->value = gotono;
567: lookback[i] = sp;
568: }
569:
570:
571:
572: short **
573: transpose(R_arg, n)
574: short **R_arg;
575: int n;
576: {
577: register short **new_R;
578: register short **temp_R;
579: register short *nedges;
580: register short *sp;
581: register int i;
582: register int k;
583:
584: nedges = NEW2(n, short);
585:
586: for (i = 0; i < n; i++)
587: {
588: sp = R_arg[i];
589: if (sp)
590: {
591: while (*sp >= 0)
592: nedges[*sp++]++;
593: }
594: }
595:
596: new_R = NEW2(n, short *);
597: temp_R = NEW2(n, short *);
598:
599: for (i = 0; i < n; i++)
600: {
601: k = nedges[i];
602: if (k > 0)
603: {
604: sp = NEW2(k + 1, short);
605: new_R[i] = sp;
606: temp_R[i] = sp;
607: sp[k] = -1;
608: }
609: }
610:
611: FREE(nedges);
612:
613: for (i = 0; i < n; i++)
614: {
615: sp = R_arg[i];
616: if (sp)
617: {
618: while (*sp >= 0)
619: *temp_R[*sp++]++ = i;
620: }
621: }
622:
623: FREE(temp_R);
624:
625: return (new_R);
626: }
627:
628:
629: void
630: compute_FOLLOWS()
631: {
632: register int i;
633:
634: digraph(includes);
635:
636: for (i = 0; i < ngotos; i++)
637: {
638: if (includes[i]) FREE(includes[i]);
639: }
640:
641: FREE(includes);
642: }
643:
644:
645: void
646: compute_lookaheads()
647: {
648: register int i;
649: register int n;
650: register unsigned *fp1;
651: register unsigned *fp2;
652: register unsigned *fp3;
653: register shorts *sp;
654: register unsigned *rowp;
655: /* register short *rulep; JF unused */
656: /* register int count; JF unused */
657: register shorts *sptmp;/* JF */
658:
659: rowp = LA;
660: n = lookaheads[nstates];
661: for (i = 0; i < n; i++)
662: {
663: fp3 = rowp + tokensetsize;
664: for (sp = lookback[i]; sp; sp = sp->next)
665: {
666: fp1 = rowp;
667: fp2 = F + tokensetsize * sp->value;
668: while (fp1 < fp3)
669: *fp1++ |= *fp2++;
670: }
671:
672: rowp = fp3;
673: }
674:
675: for (i = 0; i < n; i++)
676: {/* JF removed ref to freed storage */
677: for (sp = lookback[i]; sp; sp = sptmp) {
678: sptmp=sp->next;
679: FREE(sp);
680: }
681: }
682:
683: FREE(lookback);
684: FREE(F);
685: }
686:
687:
688: void
689: digraph(relation)
690: short **relation;
691: {
692: register int i;
693:
694: infinity = ngotos + 2;
695: INDEX = NEW2(ngotos + 1, short);
696: VERTICES = NEW2(ngotos + 1, short);
697: top = 0;
698:
699: R = relation;
700:
701: for (i = 0; i < ngotos; i++)
702: INDEX[i] = 0;
703:
704: for (i = 0; i < ngotos; i++)
705: {
706: if (INDEX[i] == 0 && R[i])
707: traverse(i);
708: }
709:
710: FREE(INDEX);
711: FREE(VERTICES);
712: }
713:
714:
715: void
716: traverse(i)
717: register int i;
718: {
719: register unsigned *fp1;
720: register unsigned *fp2;
721: register unsigned *fp3;
722: register int j;
723: register short *rp;
724:
725: int height;
726: unsigned *base;
727:
728: VERTICES[++top] = i;
729: INDEX[i] = height = top;
730:
731: base = F + i * tokensetsize;
732: fp3 = base + tokensetsize;
733:
734: rp = R[i];
735: if (rp)
736: {
737: while ((j = *rp++) >= 0)
738: {
739: if (INDEX[j] == 0)
740: traverse(j);
741:
742: if (INDEX[i] > INDEX[j])
743: INDEX[i] = INDEX[j];
744:
745: fp1 = base;
746: fp2 = F + j * tokensetsize;
747:
748: while (fp1 < fp3)
749: *fp1++ |= *fp2++;
750: }
751: }
752:
753: if (INDEX[i] == height)
754: {
755: for (;;)
756: {
757: j = VERTICES[top--];
758: INDEX[j] = infinity;
759:
760: if (i == j)
761: break;
762:
763: fp1 = base;
764: fp2 = F + j * tokensetsize;
765:
766: while (fp1 < fp3)
767: *fp2++ = *fp1++;
768: }
769: }
770: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.