Annotation of src/usr.bin/yacc/lalr.c, Revision 1.3
1.3 ! deraadt 1: /* $OpenBSD: lalr.c,v 1.4 1996/03/19 03:21:33 jtc Exp $ */
1.2 deraadt 2: /* $NetBSD: lalr.c,v 1.4 1996/03/19 03:21:33 jtc Exp $ */
3:
4: /*
5: * Copyright (c) 1989 The Regents of the University of California.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Robert Paul Corbett.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the University of
22: * California, Berkeley and its contributors.
23: * 4. Neither the name of the University nor the names of its contributors
24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37: * SUCH DAMAGE.
38: */
39:
1.1 deraadt 40: #ifndef lint
1.2 deraadt 41: #if 0
42: static char sccsid[] = "@(#)lalr.c 5.3 (Berkeley) 6/1/90";
43: #else
1.3 ! deraadt 44: static char rcsid[] = "$OpenBSD: lalr.c,v 1.4 1996/03/19 03:21:33 jtc Exp $";
1.2 deraadt 45: #endif
1.1 deraadt 46: #endif /* not lint */
47:
48: #include "defs.h"
49:
50: typedef
51: struct shorts
52: {
53: struct shorts *next;
54: short value;
55: }
56: shorts;
57:
58: int tokensetsize;
59: short *lookaheads;
60: short *LAruleno;
61: unsigned *LA;
62: short *accessing_symbol;
63: core **state_table;
64: shifts **shift_table;
65: reductions **reduction_table;
66: short *goto_map;
67: short *from_state;
68: short *to_state;
69:
70: short **transpose();
71:
72: static int infinity;
73: static int maxrhs;
74: static int ngotos;
75: static unsigned *F;
76: static short **includes;
77: static shorts **lookback;
78: static short **R;
79: static short *INDEX;
80: static short *VERTICES;
81: static int top;
82:
83:
84: lalr()
85: {
86: tokensetsize = WORDSIZE(ntokens);
87:
88: set_state_table();
89: set_accessing_symbol();
90: set_shift_table();
91: set_reduction_table();
92: set_maxrhs();
93: initialize_LA();
94: set_goto_map();
95: initialize_F();
96: build_relations();
97: compute_FOLLOWS();
98: compute_lookaheads();
99: }
100:
101:
102:
103: set_state_table()
104: {
105: register core *sp;
106:
107: state_table = NEW2(nstates, core *);
108: for (sp = first_state; sp; sp = sp->next)
109: state_table[sp->number] = sp;
110: }
111:
112:
113:
114: set_accessing_symbol()
115: {
116: register core *sp;
117:
118: accessing_symbol = NEW2(nstates, short);
119: for (sp = first_state; sp; sp = sp->next)
120: accessing_symbol[sp->number] = sp->accessing_symbol;
121: }
122:
123:
124:
125: set_shift_table()
126: {
127: register shifts *sp;
128:
129: shift_table = NEW2(nstates, shifts *);
130: for (sp = first_shift; sp; sp = sp->next)
131: shift_table[sp->number] = sp;
132: }
133:
134:
135:
136: set_reduction_table()
137: {
138: register reductions *rp;
139:
140: reduction_table = NEW2(nstates, reductions *);
141: for (rp = first_reduction; rp; rp = rp->next)
142: reduction_table[rp->number] = rp;
143: }
144:
145:
146:
147: set_maxrhs()
148: {
149: register short *itemp;
150: register short *item_end;
151: register int length;
152: register int max;
153:
154: length = 0;
155: max = 0;
156: item_end = ritem + nitems;
157: for (itemp = ritem; itemp < item_end; itemp++)
158: {
159: if (*itemp >= 0)
160: {
161: length++;
162: }
163: else
164: {
165: if (length > max) max = length;
166: length = 0;
167: }
168: }
169:
170: maxrhs = max;
171: }
172:
173:
174:
175: initialize_LA()
176: {
177: register int i, j, k;
178: register reductions *rp;
179:
180: lookaheads = NEW2(nstates + 1, short);
181:
182: k = 0;
183: for (i = 0; i < nstates; i++)
184: {
185: lookaheads[i] = k;
186: rp = reduction_table[i];
187: if (rp)
188: k += rp->nreds;
189: }
190: lookaheads[nstates] = k;
191:
192: LA = NEW2(k * tokensetsize, unsigned);
193: LAruleno = NEW2(k, short);
194: lookback = NEW2(k, shorts *);
195:
196: k = 0;
197: for (i = 0; i < nstates; i++)
198: {
199: rp = reduction_table[i];
200: if (rp)
201: {
202: for (j = 0; j < rp->nreds; j++)
203: {
204: LAruleno[k] = rp->rules[j];
205: k++;
206: }
207: }
208: }
209: }
210:
211:
212: set_goto_map()
213: {
214: register shifts *sp;
215: register int i;
216: register int symbol;
217: register int k;
218: register short *temp_map;
219: register int state2;
220: register int state1;
221:
222: goto_map = NEW2(nvars + 1, short) - ntokens;
223: temp_map = NEW2(nvars + 1, short) - ntokens;
224:
225: ngotos = 0;
226: for (sp = first_shift; sp; sp = sp->next)
227: {
228: for (i = sp->nshifts - 1; i >= 0; i--)
229: {
230: symbol = accessing_symbol[sp->shift[i]];
231:
232: if (ISTOKEN(symbol)) break;
233:
234: if (ngotos == MAXSHORT)
235: fatal("too many gotos");
236:
237: ngotos++;
238: goto_map[symbol]++;
239: }
240: }
241:
242: k = 0;
243: for (i = ntokens; i < nsyms; i++)
244: {
245: temp_map[i] = k;
246: k += goto_map[i];
247: }
248:
249: for (i = ntokens; i < nsyms; i++)
250: goto_map[i] = temp_map[i];
251:
252: goto_map[nsyms] = ngotos;
253: temp_map[nsyms] = ngotos;
254:
255: from_state = NEW2(ngotos, short);
256: to_state = NEW2(ngotos, short);
257:
258: for (sp = first_shift; sp; sp = sp->next)
259: {
260: state1 = sp->number;
261: for (i = sp->nshifts - 1; i >= 0; i--)
262: {
263: state2 = sp->shift[i];
264: symbol = accessing_symbol[state2];
265:
266: if (ISTOKEN(symbol)) break;
267:
268: k = temp_map[symbol]++;
269: from_state[k] = state1;
270: to_state[k] = state2;
271: }
272: }
273:
274: FREE(temp_map + ntokens);
275: }
276:
277:
278:
279: /* Map_goto maps a state/symbol pair into its numeric representation. */
280:
281: int
282: map_goto(state, symbol)
283: int state;
284: int symbol;
285: {
286: register int high;
287: register int low;
288: register int middle;
289: register int s;
290:
291: low = goto_map[symbol];
292: high = goto_map[symbol + 1];
293:
294: for (;;)
295: {
296: assert(low <= high);
297: middle = (low + high) >> 1;
298: s = from_state[middle];
299: if (s == state)
300: return (middle);
301: else if (s < state)
302: low = middle + 1;
303: else
304: high = middle - 1;
305: }
306: }
307:
308:
309:
310: initialize_F()
311: {
312: register int i;
313: register int j;
314: register int k;
315: register shifts *sp;
316: register short *edge;
317: register unsigned *rowp;
318: register short *rp;
319: register short **reads;
320: register int nedges;
321: register int stateno;
322: register int symbol;
323: register int nwords;
324:
325: nwords = ngotos * tokensetsize;
326: F = NEW2(nwords, unsigned);
327:
328: reads = NEW2(ngotos, short *);
329: edge = NEW2(ngotos + 1, short);
330: nedges = 0;
331:
332: rowp = F;
333: for (i = 0; i < ngotos; i++)
334: {
335: stateno = to_state[i];
336: sp = shift_table[stateno];
337:
338: if (sp)
339: {
340: k = sp->nshifts;
341:
342: for (j = 0; j < k; j++)
343: {
344: symbol = accessing_symbol[sp->shift[j]];
345: if (ISVAR(symbol))
346: break;
347: SETBIT(rowp, symbol);
348: }
349:
350: for (; j < k; j++)
351: {
352: symbol = accessing_symbol[sp->shift[j]];
353: if (nullable[symbol])
354: edge[nedges++] = map_goto(stateno, symbol);
355: }
356:
357: if (nedges)
358: {
359: reads[i] = rp = NEW2(nedges + 1, short);
360:
361: for (j = 0; j < nedges; j++)
362: rp[j] = edge[j];
363:
364: rp[nedges] = -1;
365: nedges = 0;
366: }
367: }
368:
369: rowp += tokensetsize;
370: }
371:
372: SETBIT(F, 0);
373: digraph(reads);
374:
375: for (i = 0; i < ngotos; i++)
376: {
377: if (reads[i])
378: FREE(reads[i]);
379: }
380:
381: FREE(reads);
382: FREE(edge);
383: }
384:
385:
386:
387: build_relations()
388: {
389: register int i;
390: register int j;
391: register int k;
392: register short *rulep;
393: register short *rp;
394: register shifts *sp;
395: register int length;
396: register int nedges;
397: register int done;
398: register int state1;
399: register int stateno;
400: register int symbol1;
401: register int symbol2;
402: register short *shortp;
403: register short *edge;
404: register short *states;
405: register short **new_includes;
406:
407: includes = NEW2(ngotos, short *);
408: edge = NEW2(ngotos + 1, short);
409: states = NEW2(maxrhs + 1, short);
410:
411: for (i = 0; i < ngotos; i++)
412: {
413: nedges = 0;
414: state1 = from_state[i];
415: symbol1 = accessing_symbol[to_state[i]];
416:
417: for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
418: {
419: length = 1;
420: states[0] = state1;
421: stateno = state1;
422:
423: for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
424: {
425: symbol2 = *rp;
426: sp = shift_table[stateno];
427: k = sp->nshifts;
428:
429: for (j = 0; j < k; j++)
430: {
431: stateno = sp->shift[j];
432: if (accessing_symbol[stateno] == symbol2) break;
433: }
434:
435: states[length++] = stateno;
436: }
437:
438: add_lookback_edge(stateno, *rulep, i);
439:
440: length--;
441: done = 0;
442: while (!done)
443: {
444: done = 1;
445: rp--;
446: if (ISVAR(*rp))
447: {
448: stateno = states[--length];
449: edge[nedges++] = map_goto(stateno, *rp);
450: if (nullable[*rp] && length > 0) done = 0;
451: }
452: }
453: }
454:
455: if (nedges)
456: {
457: includes[i] = shortp = NEW2(nedges + 1, short);
458: for (j = 0; j < nedges; j++)
459: shortp[j] = edge[j];
460: shortp[nedges] = -1;
461: }
462: }
463:
464: new_includes = transpose(includes, ngotos);
465:
466: for (i = 0; i < ngotos; i++)
467: if (includes[i])
468: FREE(includes[i]);
469:
470: FREE(includes);
471:
472: includes = new_includes;
473:
474: FREE(edge);
475: FREE(states);
476: }
477:
478:
479: add_lookback_edge(stateno, ruleno, gotono)
480: int stateno, ruleno, gotono;
481: {
482: register int i, k;
483: register int found;
484: register shorts *sp;
485:
486: i = lookaheads[stateno];
487: k = lookaheads[stateno + 1];
488: found = 0;
489: while (!found && i < k)
490: {
491: if (LAruleno[i] == ruleno)
492: found = 1;
493: else
494: ++i;
495: }
496: assert(found);
497:
498: sp = NEW(shorts);
499: sp->next = lookback[i];
500: sp->value = gotono;
501: lookback[i] = sp;
502: }
503:
504:
505:
506: short **
507: transpose(R, n)
508: short **R;
509: int n;
510: {
511: register short **new_R;
512: register short **temp_R;
513: register short *nedges;
514: register short *sp;
515: register int i;
516: register int k;
517:
518: nedges = NEW2(n, short);
519:
520: for (i = 0; i < n; i++)
521: {
522: sp = R[i];
523: if (sp)
524: {
525: while (*sp >= 0)
526: nedges[*sp++]++;
527: }
528: }
529:
530: new_R = NEW2(n, short *);
531: temp_R = NEW2(n, short *);
532:
533: for (i = 0; i < n; i++)
534: {
535: k = nedges[i];
536: if (k > 0)
537: {
538: sp = NEW2(k + 1, short);
539: new_R[i] = sp;
540: temp_R[i] = sp;
541: sp[k] = -1;
542: }
543: }
544:
545: FREE(nedges);
546:
547: for (i = 0; i < n; i++)
548: {
549: sp = R[i];
550: if (sp)
551: {
552: while (*sp >= 0)
553: *temp_R[*sp++]++ = i;
554: }
555: }
556:
557: FREE(temp_R);
558:
559: return (new_R);
560: }
561:
562:
563:
564: compute_FOLLOWS()
565: {
566: digraph(includes);
567: }
568:
569:
570: compute_lookaheads()
571: {
572: register int i, n;
573: register unsigned *fp1, *fp2, *fp3;
574: register shorts *sp, *next;
575: register unsigned *rowp;
576:
577: rowp = LA;
578: n = lookaheads[nstates];
579: for (i = 0; i < n; i++)
580: {
581: fp3 = rowp + tokensetsize;
582: for (sp = lookback[i]; sp; sp = sp->next)
583: {
584: fp1 = rowp;
585: fp2 = F + tokensetsize * sp->value;
586: while (fp1 < fp3)
587: *fp1++ |= *fp2++;
588: }
589: rowp = fp3;
590: }
591:
592: for (i = 0; i < n; i++)
593: for (sp = lookback[i]; sp; sp = next)
594: {
595: next = sp->next;
596: FREE(sp);
597: }
598:
599: FREE(lookback);
600: FREE(F);
601: }
602:
603:
604: digraph(relation)
605: short **relation;
606: {
607: register int i;
608:
609: infinity = ngotos + 2;
610: INDEX = NEW2(ngotos + 1, short);
611: VERTICES = NEW2(ngotos + 1, short);
612: top = 0;
613:
614: R = relation;
615:
616: for (i = 0; i < ngotos; i++)
617: INDEX[i] = 0;
618:
619: for (i = 0; i < ngotos; i++)
620: {
621: if (INDEX[i] == 0 && R[i])
622: traverse(i);
623: }
624:
625: FREE(INDEX);
626: FREE(VERTICES);
627: }
628:
629:
630:
631: traverse(i)
632: register int i;
633: {
634: register unsigned *fp1;
635: register unsigned *fp2;
636: register unsigned *fp3;
637: register int j;
638: register short *rp;
639:
640: int height;
641: unsigned *base;
642:
643: VERTICES[++top] = i;
644: INDEX[i] = height = top;
645:
646: base = F + i * tokensetsize;
647: fp3 = base + tokensetsize;
648:
649: rp = R[i];
650: if (rp)
651: {
652: while ((j = *rp++) >= 0)
653: {
654: if (INDEX[j] == 0)
655: traverse(j);
656:
657: if (INDEX[i] > INDEX[j])
658: INDEX[i] = INDEX[j];
659:
660: fp1 = base;
661: fp2 = F + j * tokensetsize;
662:
663: while (fp1 < fp3)
664: *fp1++ |= *fp2++;
665: }
666: }
667:
668: if (INDEX[i] == height)
669: {
670: for (;;)
671: {
672: j = VERTICES[top--];
673: INDEX[j] = infinity;
674:
675: if (i == j)
676: break;
677:
678: fp1 = base;
679: fp2 = F + j * tokensetsize;
680:
681: while (fp1 < fp3)
682: *fp2++ = *fp1++;
683: }
684: }
685: }