Annotation of src/usr.bin/yacc/lalr.c, Revision 1.15
1.15 ! tedu 1: /* $OpenBSD: lalr.c,v 1.14 2014/01/10 11:19:31 sthen 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:
1.15 ! tedu 38: typedef struct shorts {
! 39: struct shorts *next;
! 40: short value;
! 41: } shorts;
1.1 deraadt 42:
43: int tokensetsize;
44: short *lookaheads;
45: short *LAruleno;
46: unsigned *LA;
47: short *accessing_symbol;
48: core **state_table;
49: shifts **shift_table;
50: reductions **reduction_table;
51: short *goto_map;
52: short *from_state;
53: short *to_state;
54:
55: short **transpose();
1.6 millert 56: void set_state_table(void);
57: void set_accessing_symbol(void);
58: void set_shift_table(void);
59: void set_reduction_table(void);
60: void set_maxrhs(void);
61: void initialize_LA(void);
62: void set_goto_map(void);
63: void initialize_F(void);
64: void build_relations(void);
65: void compute_FOLLOWS(void);
66: void compute_lookaheads(void);
67: int map_goto(int, int);
68: void digraph(short **);
69: void add_lookback_edge(int, int, int);
70: void traverse(int);
1.1 deraadt 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:
1.4 pvalchev 83: void
1.8 pvalchev 84: lalr(void)
1.1 deraadt 85: {
1.15 ! tedu 86: tokensetsize = WORDSIZE(ntokens);
1.1 deraadt 87:
1.15 ! tedu 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: free_derives();
! 100: free_nullable();
1.1 deraadt 101: }
102:
103:
1.4 pvalchev 104: void
1.8 pvalchev 105: set_state_table(void)
1.1 deraadt 106: {
1.15 ! tedu 107: core *sp;
1.1 deraadt 108:
1.15 ! tedu 109: state_table = NEW2(nstates, core *);
! 110: for (sp = first_state; sp; sp = sp->next)
! 111: state_table[sp->number] = sp;
1.1 deraadt 112: }
113:
114:
1.4 pvalchev 115: void
1.8 pvalchev 116: set_accessing_symbol(void)
1.1 deraadt 117: {
1.15 ! tedu 118: core *sp;
1.1 deraadt 119:
1.15 ! tedu 120: accessing_symbol = NEW2(nstates, short);
! 121: for (sp = first_state; sp; sp = sp->next)
! 122: accessing_symbol[sp->number] = sp->accessing_symbol;
1.1 deraadt 123: }
124:
125:
1.4 pvalchev 126: void
1.8 pvalchev 127: set_shift_table(void)
1.1 deraadt 128: {
1.15 ! tedu 129: shifts *sp;
1.1 deraadt 130:
1.15 ! tedu 131: shift_table = NEW2(nstates, shifts *);
! 132: for (sp = first_shift; sp; sp = sp->next)
! 133: shift_table[sp->number] = sp;
1.1 deraadt 134: }
135:
136:
1.4 pvalchev 137: void
1.8 pvalchev 138: set_reduction_table(void)
1.1 deraadt 139: {
1.15 ! tedu 140: reductions *rp;
1.1 deraadt 141:
1.15 ! tedu 142: reduction_table = NEW2(nstates, reductions *);
! 143: for (rp = first_reduction; rp; rp = rp->next)
! 144: reduction_table[rp->number] = rp;
1.1 deraadt 145: }
146:
147:
1.4 pvalchev 148: void
1.8 pvalchev 149: set_maxrhs(void)
1.1 deraadt 150: {
1.15 ! tedu 151: short *itemp;
! 152: short *item_end;
! 153: int length;
! 154: int max;
! 155:
! 156: length = 0;
! 157: max = 0;
! 158: item_end = ritem + nitems;
! 159: for (itemp = ritem; itemp < item_end; itemp++) {
! 160: if (*itemp >= 0) {
! 161: length++;
! 162: } else {
! 163: if (length > max) max = length;
! 164: length = 0;
! 165: }
1.1 deraadt 166: }
167:
1.15 ! tedu 168: maxrhs = max;
1.1 deraadt 169: }
170:
171:
1.4 pvalchev 172: void
1.8 pvalchev 173: initialize_LA(void)
1.1 deraadt 174: {
1.15 ! tedu 175: int i, j, k;
! 176: reductions *rp;
1.1 deraadt 177:
1.15 ! tedu 178: lookaheads = NEW2(nstates + 1, short);
1.1 deraadt 179:
1.15 ! tedu 180: k = 0;
! 181: for (i = 0; i < nstates; i++) {
! 182: lookaheads[i] = k;
! 183: rp = reduction_table[i];
! 184: if (rp)
! 185: k += rp->nreds;
! 186: }
! 187: lookaheads[nstates] = k;
! 188:
! 189: LA = NEW2(k * tokensetsize, unsigned);
! 190: LAruleno = NEW2(k, short);
! 191: lookback = NEW2(k, shorts *);
! 192:
! 193: k = 0;
! 194: for (i = 0; i < nstates; i++) {
! 195: rp = reduction_table[i];
! 196: if (rp) {
! 197: for (j = 0; j < rp->nreds; j++) {
! 198: LAruleno[k] = rp->rules[j];
! 199: k++;
! 200: }
! 201: }
1.1 deraadt 202: }
203: }
204:
1.4 pvalchev 205: void
1.8 pvalchev 206: set_goto_map(void)
1.1 deraadt 207: {
1.15 ! tedu 208: shifts *sp;
! 209: int i;
! 210: int symbol;
! 211: int k;
! 212: short *temp_map;
! 213: int state2;
! 214: int state1;
! 215:
! 216: goto_map = NEW2(nvars + 1, short) - ntokens;
! 217: temp_map = NEW2(nvars + 1, short) - ntokens;
! 218:
! 219: ngotos = 0;
! 220: for (sp = first_shift; sp; sp = sp->next) {
! 221: for (i = sp->nshifts - 1; i >= 0; i--) {
! 222: symbol = accessing_symbol[sp->shift[i]];
! 223:
! 224: if (ISTOKEN(symbol)) break;
! 225:
! 226: if (ngotos == MAXSHORT)
! 227: fatal("too many gotos");
! 228:
! 229: ngotos++;
! 230: goto_map[symbol]++;
! 231: }
! 232: }
! 233:
! 234: k = 0;
! 235: for (i = ntokens; i < nsyms; i++) {
! 236: temp_map[i] = k;
! 237: k += goto_map[i];
! 238: }
! 239:
! 240: for (i = ntokens; i < nsyms; i++)
! 241: goto_map[i] = temp_map[i];
! 242:
! 243: goto_map[nsyms] = ngotos;
! 244: temp_map[nsyms] = ngotos;
! 245:
! 246: from_state = NEW2(ngotos, short);
! 247: to_state = NEW2(ngotos, short);
! 248:
! 249: for (sp = first_shift; sp; sp = sp->next) {
! 250: state1 = sp->number;
! 251: for (i = sp->nshifts - 1; i >= 0; i--) {
! 252: state2 = sp->shift[i];
! 253: symbol = accessing_symbol[state2];
! 254:
! 255: if (ISTOKEN(symbol)) break;
! 256:
! 257: k = temp_map[symbol]++;
! 258: from_state[k] = state1;
! 259: to_state[k] = state2;
! 260: }
1.1 deraadt 261: }
262:
1.15 ! tedu 263: free(temp_map + ntokens);
1.1 deraadt 264: }
265:
266:
267:
268: /* Map_goto maps a state/symbol pair into its numeric representation. */
269:
270: int
1.8 pvalchev 271: map_goto(int state, int symbol)
1.1 deraadt 272: {
1.15 ! tedu 273: int high;
! 274: int low;
! 275: int middle;
! 276: int s;
! 277:
! 278: low = goto_map[symbol];
! 279: high = goto_map[symbol + 1];
! 280:
! 281: for (;;) {
! 282: assert(low <= high);
! 283: middle = (low + high) >> 1;
! 284: s = from_state[middle];
! 285: if (s == state)
! 286: return (middle);
! 287: else if (s < state)
! 288: low = middle + 1;
! 289: else
! 290: high = middle - 1;
! 291: }
1.1 deraadt 292: }
293:
294:
1.4 pvalchev 295: void
1.8 pvalchev 296: initialize_F(void)
1.1 deraadt 297: {
1.15 ! tedu 298: int i;
! 299: int j;
! 300: int k;
! 301: shifts *sp;
! 302: short *edge;
! 303: unsigned *rowp;
! 304: short *rp;
! 305: short **reads;
! 306: int nedges;
! 307: int stateno;
! 308: int symbol;
! 309: int nwords;
! 310:
! 311: nwords = ngotos * tokensetsize;
! 312: F = NEW2(nwords, unsigned);
! 313:
! 314: reads = NEW2(ngotos, short *);
! 315: edge = NEW2(ngotos + 1, short);
! 316: nedges = 0;
! 317:
! 318: rowp = F;
! 319: for (i = 0; i < ngotos; i++) {
! 320: stateno = to_state[i];
! 321: sp = shift_table[stateno];
! 322:
! 323: if (sp) {
! 324: k = sp->nshifts;
! 325:
! 326: for (j = 0; j < k; j++) {
! 327: symbol = accessing_symbol[sp->shift[j]];
! 328: if (ISVAR(symbol))
! 329: break;
! 330: SETBIT(rowp, symbol);
! 331: }
! 332:
! 333: for (; j < k; j++) {
! 334: symbol = accessing_symbol[sp->shift[j]];
! 335: if (nullable[symbol])
! 336: edge[nedges++] = map_goto(stateno, symbol);
! 337: }
! 338:
! 339: if (nedges) {
! 340: reads[i] = rp = NEW2(nedges + 1, short);
! 341:
! 342: for (j = 0; j < nedges; j++)
! 343: rp[j] = edge[j];
! 344:
! 345: rp[nedges] = -1;
! 346: nedges = 0;
! 347: }
! 348: }
1.1 deraadt 349:
1.15 ! tedu 350: rowp += tokensetsize;
! 351: }
! 352:
! 353: SETBIT(F, 0);
! 354: digraph(reads);
! 355:
! 356: for (i = 0; i < ngotos; i++) {
! 357: if (reads[i])
! 358: free(reads[i]);
! 359: }
! 360:
! 361: free(reads);
! 362: free(edge);
1.1 deraadt 363: }
364:
365:
1.4 pvalchev 366: void
1.8 pvalchev 367: build_relations(void)
1.1 deraadt 368: {
1.15 ! tedu 369: int i;
! 370: int j;
! 371: int k;
! 372: short *rulep;
! 373: short *rp;
! 374: shifts *sp;
! 375: int length;
! 376: int nedges;
! 377: int done;
! 378: int state1;
! 379: int stateno;
! 380: int symbol1;
! 381: int symbol2;
! 382: short *shortp;
! 383: short *edge;
! 384: short *states;
! 385: short **new_includes;
! 386:
! 387: includes = NEW2(ngotos, short *);
! 388: edge = NEW2(ngotos + 1, short);
! 389: states = NEW2(maxrhs + 1, short);
! 390:
! 391: for (i = 0; i < ngotos; i++) {
! 392: nedges = 0;
! 393: state1 = from_state[i];
! 394: symbol1 = accessing_symbol[to_state[i]];
! 395:
! 396: for (rulep = derives[symbol1]; *rulep >= 0; rulep++) {
! 397: length = 1;
! 398: states[0] = state1;
! 399: stateno = state1;
! 400:
! 401: for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++) {
! 402: symbol2 = *rp;
! 403: sp = shift_table[stateno];
! 404: k = sp->nshifts;
! 405:
! 406: for (j = 0; j < k; j++) {
! 407: stateno = sp->shift[j];
! 408: if (accessing_symbol[stateno] == symbol2)
! 409: break;
! 410: }
! 411:
! 412: states[length++] = stateno;
! 413: }
! 414:
! 415: add_lookback_edge(stateno, *rulep, i);
! 416:
! 417: length--;
! 418: done = 0;
! 419: while (!done) {
! 420: done = 1;
! 421: rp--;
! 422: if (ISVAR(*rp)) {
! 423: stateno = states[--length];
! 424: edge[nedges++] = map_goto(stateno, *rp);
! 425: if (nullable[*rp] && length > 0)
! 426: done = 0;
! 427: }
! 428: }
! 429: }
1.1 deraadt 430:
1.15 ! tedu 431: if (nedges) {
! 432: includes[i] = shortp = NEW2(nedges + 1, short);
! 433: for (j = 0; j < nedges; j++)
! 434: shortp[j] = edge[j];
! 435: shortp[nedges] = -1;
! 436: }
! 437: }
! 438:
! 439: new_includes = transpose(includes, ngotos);
1.1 deraadt 440:
1.15 ! tedu 441: for (i = 0; i < ngotos; i++)
! 442: if (includes[i])
! 443: free(includes[i]);
1.1 deraadt 444:
1.15 ! tedu 445: free(includes);
! 446:
! 447: includes = new_includes;
! 448:
! 449: free(edge);
! 450: free(states);
1.1 deraadt 451: }
452:
1.4 pvalchev 453: void
1.8 pvalchev 454: add_lookback_edge(int stateno, int ruleno, int gotono)
1.1 deraadt 455: {
1.15 ! tedu 456: int i, k;
! 457: int found;
! 458: shorts *sp;
! 459:
! 460: i = lookaheads[stateno];
! 461: k = lookaheads[stateno + 1];
! 462: found = 0;
! 463: while (!found && i < k) {
! 464: if (LAruleno[i] == ruleno)
! 465: found = 1;
! 466: else
! 467: ++i;
! 468: }
! 469: assert(found);
! 470:
! 471: sp = NEW(shorts);
! 472: sp->next = lookback[i];
! 473: sp->value = gotono;
! 474: lookback[i] = sp;
1.1 deraadt 475: }
476:
477:
478:
479: short **
1.8 pvalchev 480: transpose(short **R, int n)
1.1 deraadt 481: {
1.15 ! tedu 482: short **new_R;
! 483: short **temp_R;
! 484: short *nedges;
! 485: short *sp;
! 486: int i;
! 487: int k;
! 488:
! 489: nedges = NEW2(n, short);
! 490:
! 491: for (i = 0; i < n; i++) {
! 492: sp = R[i];
! 493: if (sp) {
! 494: while (*sp >= 0)
! 495: nedges[*sp++]++;
! 496: }
! 497: }
! 498:
! 499: new_R = NEW2(n, short *);
! 500: temp_R = NEW2(n, short *);
! 501:
! 502: for (i = 0; i < n; i++) {
! 503: k = nedges[i];
! 504: if (k > 0) {
! 505: sp = NEW2(k + 1, short);
! 506: new_R[i] = sp;
! 507: temp_R[i] = sp;
! 508: sp[k] = -1;
! 509: }
! 510: }
! 511:
! 512: free(nedges);
! 513:
! 514: for (i = 0; i < n; i++) {
! 515: sp = R[i];
! 516: if (sp) {
! 517: while (*sp >= 0)
! 518: *temp_R[*sp++]++ = i;
! 519: }
1.1 deraadt 520: }
521:
1.15 ! tedu 522: free(temp_R);
1.1 deraadt 523:
1.15 ! tedu 524: return (new_R);
1.1 deraadt 525: }
526:
527:
1.4 pvalchev 528: void
1.8 pvalchev 529: compute_FOLLOWS(void)
1.1 deraadt 530: {
1.15 ! tedu 531: digraph(includes);
1.1 deraadt 532: }
533:
1.4 pvalchev 534: void
1.8 pvalchev 535: compute_lookaheads(void)
1.1 deraadt 536: {
1.15 ! tedu 537: int i, n;
! 538: unsigned *fp1, *fp2, *fp3;
! 539: shorts *sp, *next;
! 540: unsigned *rowp;
! 541:
! 542: rowp = LA;
! 543: n = lookaheads[nstates];
! 544: for (i = 0; i < n; i++) {
! 545: fp3 = rowp + tokensetsize;
! 546: for (sp = lookback[i]; sp; sp = sp->next) {
! 547: fp1 = rowp;
! 548: fp2 = F + tokensetsize * sp->value;
! 549: while (fp1 < fp3)
! 550: *fp1++ |= *fp2++;
! 551: }
! 552: rowp = fp3;
! 553: }
! 554:
! 555: for (i = 0; i < n; i++)
! 556: for (sp = lookback[i]; sp; sp = next) {
! 557: next = sp->next;
! 558: free(sp);
! 559: }
1.1 deraadt 560:
1.15 ! tedu 561: free(lookback);
! 562: free(F);
1.1 deraadt 563: }
564:
1.4 pvalchev 565: void
1.8 pvalchev 566: digraph(short **relation)
1.1 deraadt 567: {
1.15 ! tedu 568: int i;
1.1 deraadt 569:
1.15 ! tedu 570: infinity = ngotos + 2;
! 571: INDEX = NEW2(ngotos + 1, short);
! 572: VERTICES = NEW2(ngotos + 1, short);
! 573: top = 0;
! 574: R = relation;
! 575:
! 576: memset(INDEX, 0, ngotos * sizeof(short));
! 577: for (i = 0; i < ngotos; i++)
! 578: if (R[i])
! 579: traverse(i);
1.1 deraadt 580:
1.15 ! tedu 581: free(INDEX);
! 582: free(VERTICES);
1.1 deraadt 583: }
584:
585:
1.4 pvalchev 586: void
1.8 pvalchev 587: traverse(int i)
1.1 deraadt 588: {
1.15 ! tedu 589: unsigned *fp1;
! 590: unsigned *fp2;
! 591: unsigned *fp3;
! 592: int j;
! 593: short *rp;
! 594:
! 595: int height;
! 596: unsigned *base;
! 597:
! 598: VERTICES[++top] = i;
! 599: INDEX[i] = height = top;
! 600:
! 601: base = F + i * tokensetsize;
! 602: fp3 = base + tokensetsize;
! 603:
! 604: rp = R[i];
! 605: if (rp) {
! 606: while ((j = *rp++) >= 0) {
! 607: if (INDEX[j] == 0)
! 608: traverse(j);
1.14 sthen 609:
1.15 ! tedu 610: if (INDEX[i] > INDEX[j])
! 611: INDEX[i] = INDEX[j];
1.1 deraadt 612:
1.15 ! tedu 613: fp1 = base;
! 614: fp2 = F + j * tokensetsize;
1.1 deraadt 615:
1.15 ! tedu 616: while (fp1 < fp3)
! 617: *fp1++ |= *fp2++;
! 618: }
1.1 deraadt 619: }
620:
1.15 ! tedu 621: if (INDEX[i] == height) {
! 622: for (;;) {
! 623: j = VERTICES[top--];
! 624: INDEX[j] = infinity;
1.1 deraadt 625:
1.15 ! tedu 626: if (i == j)
! 627: break;
1.1 deraadt 628:
1.15 ! tedu 629: fp1 = base;
! 630: fp2 = F + j * tokensetsize;
1.1 deraadt 631:
1.15 ! tedu 632: while (fp1 < fp3)
! 633: *fp2++ = *fp1++;
! 634: }
1.1 deraadt 635: }
636: }