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