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