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