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