|
|
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[] = "@(#)lr0.c 5.2 (Berkeley) 6/1/90"; ! 25: #endif /* not lint */ ! 26: ! 27: #include "defs.h" ! 28: ! 29: extern short *itemset; ! 30: extern short *itemsetend; ! 31: extern unsigned *ruleset; ! 32: ! 33: int nstates; ! 34: core *first_state; ! 35: shifts *first_shift; ! 36: reductions *first_reduction; ! 37: ! 38: int get_state(); ! 39: core *new_state(); ! 40: ! 41: static core *this_state; ! 42: static core *last_state; ! 43: static shifts *last_shift; ! 44: static reductions *last_reduction; ! 45: ! 46: static int nshifts; ! 47: static short *shift_symbol; ! 48: ! 49: static short *redset; ! 50: static short *shiftset; ! 51: ! 52: static short **kernel_base; ! 53: static short **kernel_end; ! 54: static short *kernel_items; ! 55: ! 56: static core **state_table; ! 57: ! 58: ! 59: allocate_itemsets() ! 60: { ! 61: register short *itemp; ! 62: register short *item_end; ! 63: register int symbol; ! 64: register int i; ! 65: register int count; ! 66: register int max; ! 67: register short *symbol_count; ! 68: ! 69: count = 0; ! 70: symbol_count = NEW2(nsyms, short); ! 71: ! 72: item_end = ritem + nitems; ! 73: for (itemp = ritem; itemp < item_end; itemp++) ! 74: { ! 75: symbol = *itemp; ! 76: if (symbol >= 0) ! 77: { ! 78: count++; ! 79: symbol_count[symbol]++; ! 80: } ! 81: } ! 82: ! 83: kernel_base = NEW2(nsyms, short *); ! 84: kernel_items = NEW2(count, short); ! 85: ! 86: count = 0; ! 87: max = 0; ! 88: for (i = 0; i < nsyms; i++) ! 89: { ! 90: kernel_base[i] = kernel_items + count; ! 91: count += symbol_count[i]; ! 92: if (max < symbol_count[i]) ! 93: max = symbol_count[i]; ! 94: } ! 95: ! 96: shift_symbol = symbol_count; ! 97: kernel_end = NEW2(nsyms, short *); ! 98: } ! 99: ! 100: ! 101: ! 102: allocate_storage() ! 103: { ! 104: allocate_itemsets(); ! 105: ! 106: shiftset = NEW2(nsyms, short); ! 107: redset = NEW2(nrules + 1, short); ! 108: state_table = NEW2(nitems, core *); ! 109: } ! 110: ! 111: ! 112: ! 113: append_states() ! 114: { ! 115: register int i; ! 116: register int j; ! 117: register int symbol; ! 118: ! 119: #ifdef TRACE ! 120: fprintf(stderr, "Entering append_states\n"); ! 121: #endif ! 122: ! 123: for (i = 1; i < nshifts; i++) ! 124: { ! 125: symbol = shift_symbol[i]; ! 126: j = i; ! 127: while (j > 0 && shift_symbol[j - 1] > symbol) ! 128: { ! 129: shift_symbol[j] = shift_symbol[j - 1]; ! 130: j--; ! 131: } ! 132: shift_symbol[j] = symbol; ! 133: } ! 134: ! 135: for (i = 0; i < nshifts; i++) ! 136: { ! 137: symbol = shift_symbol[i]; ! 138: shiftset[i] = get_state(symbol); ! 139: } ! 140: } ! 141: ! 142: ! 143: free_storage() ! 144: { ! 145: FREE(shift_symbol); ! 146: FREE(redset); ! 147: FREE(shiftset); ! 148: FREE(kernel_base); ! 149: FREE(kernel_end); ! 150: FREE(kernel_items); ! 151: FREE(state_table); ! 152: } ! 153: ! 154: ! 155: ! 156: generate_states() ! 157: { ! 158: allocate_storage(); ! 159: itemset = NEW2(nitems, short); ! 160: ruleset = NEW2(WORDSIZE(nrules), unsigned); ! 161: set_first_derives(); ! 162: initialize_states(); ! 163: ! 164: while (this_state) ! 165: { ! 166: closure(this_state->items, this_state->nitems); ! 167: save_reductions(); ! 168: new_itemsets(); ! 169: append_states(); ! 170: ! 171: if (nshifts > 0) ! 172: save_shifts(); ! 173: ! 174: this_state = this_state->next; ! 175: } ! 176: ! 177: finalize_closure(); ! 178: free_storage(); ! 179: } ! 180: ! 181: ! 182: ! 183: int ! 184: get_state(symbol) ! 185: int symbol; ! 186: { ! 187: register int key; ! 188: register short *isp1; ! 189: register short *isp2; ! 190: register short *iend; ! 191: register core *sp; ! 192: register int found; ! 193: ! 194: int n; ! 195: ! 196: #ifdef TRACE ! 197: fprintf(stderr, "Entering get_state, symbol = %d\n", symbol); ! 198: #endif ! 199: ! 200: isp1 = kernel_base[symbol]; ! 201: iend = kernel_end[symbol]; ! 202: n = iend - isp1; ! 203: ! 204: key = *isp1; ! 205: assert(0 <= key && key < nitems); ! 206: sp = state_table[key]; ! 207: if (sp) ! 208: { ! 209: found = 0; ! 210: while (!found) ! 211: { ! 212: if (sp->nitems == n) ! 213: { ! 214: found = 1; ! 215: isp1 = kernel_base[symbol]; ! 216: isp2 = sp->items; ! 217: ! 218: while (found && isp1 < iend) ! 219: { ! 220: if (*isp1++ != *isp2++) ! 221: found = 0; ! 222: } ! 223: } ! 224: ! 225: if (!found) ! 226: { ! 227: if (sp->link) ! 228: { ! 229: sp = sp->link; ! 230: } ! 231: else ! 232: { ! 233: sp = sp->link = new_state(symbol); ! 234: found = 1; ! 235: } ! 236: } ! 237: } ! 238: } ! 239: else ! 240: { ! 241: state_table[key] = sp = new_state(symbol); ! 242: } ! 243: ! 244: return (sp->number); ! 245: } ! 246: ! 247: ! 248: ! 249: initialize_states() ! 250: { ! 251: register int i; ! 252: register short *start_derives; ! 253: register core *p; ! 254: ! 255: start_derives = derives[start_symbol]; ! 256: for (i = 0; start_derives[i] >= 0; ++i) ! 257: continue; ! 258: ! 259: p = (core *) MALLOC(sizeof(core) + i*sizeof(short)); ! 260: if (p == 0) no_space(); ! 261: ! 262: p->next = 0; ! 263: p->link = 0; ! 264: p->number = 0; ! 265: p->accessing_symbol = 0; ! 266: p->nitems = i; ! 267: ! 268: for (i = 0; start_derives[i] >= 0; ++i) ! 269: p->items[i] = rrhs[start_derives[i]]; ! 270: ! 271: first_state = last_state = this_state = p; ! 272: nstates = 1; ! 273: } ! 274: ! 275: ! 276: new_itemsets() ! 277: { ! 278: register int i; ! 279: register int shiftcount; ! 280: register short *isp; ! 281: register short *ksp; ! 282: register int symbol; ! 283: ! 284: for (i = 0; i < nsyms; i++) ! 285: kernel_end[i] = 0; ! 286: ! 287: shiftcount = 0; ! 288: isp = itemset; ! 289: while (isp < itemsetend) ! 290: { ! 291: i = *isp++; ! 292: symbol = ritem[i]; ! 293: if (symbol > 0) ! 294: { ! 295: ksp = kernel_end[symbol]; ! 296: ! 297: if (!ksp) ! 298: { ! 299: shift_symbol[shiftcount++] = symbol; ! 300: ksp = kernel_base[symbol]; ! 301: } ! 302: ! 303: *ksp++ = i + 1; ! 304: kernel_end[symbol] = ksp; ! 305: } ! 306: } ! 307: ! 308: nshifts = shiftcount; ! 309: } ! 310: ! 311: ! 312: ! 313: core * ! 314: new_state(symbol) ! 315: int symbol; ! 316: { ! 317: register int n; ! 318: register core *p; ! 319: register short *isp1; ! 320: register short *isp2; ! 321: register short *iend; ! 322: ! 323: #ifdef TRACE ! 324: fprintf(stderr, "Entering new_state, symbol = %d\n", symbol); ! 325: #endif ! 326: ! 327: if (nstates >= MAXSHORT) ! 328: fatal("too many states"); ! 329: ! 330: isp1 = kernel_base[symbol]; ! 331: iend = kernel_end[symbol]; ! 332: n = iend - isp1; ! 333: ! 334: p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short))); ! 335: p->accessing_symbol = symbol; ! 336: p->number = nstates; ! 337: p->nitems = n; ! 338: ! 339: isp2 = p->items; ! 340: while (isp1 < iend) ! 341: *isp2++ = *isp1++; ! 342: ! 343: last_state->next = p; ! 344: last_state = p; ! 345: ! 346: nstates++; ! 347: ! 348: return (p); ! 349: } ! 350: ! 351: ! 352: /* show_cores is used for debugging */ ! 353: ! 354: show_cores() ! 355: { ! 356: core *p; ! 357: int i, j, k, n; ! 358: int itemno; ! 359: ! 360: k = 0; ! 361: for (p = first_state; p; ++k, p = p->next) ! 362: { ! 363: if (k) printf("\n"); ! 364: printf("state %d, number = %d, accessing symbol = %s\n", ! 365: k, p->number, symbol_name[p->accessing_symbol]); ! 366: n = p->nitems; ! 367: for (i = 0; i < n; ++i) ! 368: { ! 369: itemno = p->items[i]; ! 370: printf("%4d ", itemno); ! 371: j = itemno; ! 372: while (ritem[j] >= 0) ++j; ! 373: printf("%s :", symbol_name[rlhs[-ritem[j]]]); ! 374: j = rrhs[-ritem[j]]; ! 375: while (j < itemno) ! 376: printf(" %s", symbol_name[ritem[j++]]); ! 377: printf(" ."); ! 378: while (ritem[j] >= 0) ! 379: printf(" %s", symbol_name[ritem[j++]]); ! 380: printf("\n"); ! 381: fflush(stdout); ! 382: } ! 383: } ! 384: } ! 385: ! 386: ! 387: /* show_ritems is used for debugging */ ! 388: ! 389: show_ritems() ! 390: { ! 391: int i; ! 392: ! 393: for (i = 0; i < nitems; ++i) ! 394: printf("ritem[%d] = %d\n", i, ritem[i]); ! 395: } ! 396: ! 397: ! 398: /* show_rrhs is used for debugging */ ! 399: show_rrhs() ! 400: { ! 401: int i; ! 402: ! 403: for (i = 0; i < nrules; ++i) ! 404: printf("rrhs[%d] = %d\n", i, rrhs[i]); ! 405: } ! 406: ! 407: ! 408: /* show_shifts is used for debugging */ ! 409: ! 410: show_shifts() ! 411: { ! 412: shifts *p; ! 413: int i, j, k; ! 414: ! 415: k = 0; ! 416: for (p = first_shift; p; ++k, p = p->next) ! 417: { ! 418: if (k) printf("\n"); ! 419: printf("shift %d, number = %d, nshifts = %d\n", k, p->number, ! 420: p->nshifts); ! 421: j = p->nshifts; ! 422: for (i = 0; i < j; ++i) ! 423: printf("\t%d\n", p->shift[i]); ! 424: } ! 425: } ! 426: ! 427: ! 428: save_shifts() ! 429: { ! 430: register shifts *p; ! 431: register short *sp1; ! 432: register short *sp2; ! 433: register short *send; ! 434: ! 435: p = (shifts *) allocate((unsigned) (sizeof(shifts) + ! 436: (nshifts - 1) * sizeof(short))); ! 437: ! 438: p->number = this_state->number; ! 439: p->nshifts = nshifts; ! 440: ! 441: sp1 = shiftset; ! 442: sp2 = p->shift; ! 443: send = shiftset + nshifts; ! 444: ! 445: while (sp1 < send) ! 446: *sp2++ = *sp1++; ! 447: ! 448: if (last_shift) ! 449: { ! 450: last_shift->next = p; ! 451: last_shift = p; ! 452: } ! 453: else ! 454: { ! 455: first_shift = p; ! 456: last_shift = p; ! 457: } ! 458: } ! 459: ! 460: ! 461: ! 462: save_reductions() ! 463: { ! 464: register short *isp; ! 465: register short *rp1; ! 466: register short *rp2; ! 467: register int item; ! 468: register int count; ! 469: register reductions *p; ! 470: ! 471: short *rend; ! 472: ! 473: count = 0; ! 474: for (isp = itemset; isp < itemsetend; isp++) ! 475: { ! 476: item = ritem[*isp]; ! 477: if (item < 0) ! 478: { ! 479: redset[count++] = -item; ! 480: } ! 481: } ! 482: ! 483: if (count) ! 484: { ! 485: p = (reductions *) allocate((unsigned) (sizeof(reductions) + ! 486: (count - 1) * sizeof(short))); ! 487: ! 488: p->number = this_state->number; ! 489: p->nreds = count; ! 490: ! 491: rp1 = redset; ! 492: rp2 = p->rules; ! 493: rend = rp1 + count; ! 494: ! 495: while (rp1 < rend) ! 496: *rp2++ = *rp1++; ! 497: ! 498: if (last_reduction) ! 499: { ! 500: last_reduction->next = p; ! 501: last_reduction = p; ! 502: } ! 503: else ! 504: { ! 505: first_reduction = p; ! 506: last_reduction = p; ! 507: } ! 508: } ! 509: } ! 510: ! 511: ! 512: set_derives() ! 513: { ! 514: register int i, k; ! 515: register int lhs; ! 516: register short *rules; ! 517: ! 518: derives = NEW2(nsyms, short *); ! 519: rules = NEW2(nvars + nrules, short); ! 520: ! 521: k = 0; ! 522: for (lhs = start_symbol; lhs < nsyms; lhs++) ! 523: { ! 524: derives[lhs] = rules + k; ! 525: for (i = 0; i < nrules; i++) ! 526: { ! 527: if (rlhs[i] == lhs) ! 528: { ! 529: rules[k] = i; ! 530: k++; ! 531: } ! 532: } ! 533: rules[k] = -1; ! 534: k++; ! 535: } ! 536: ! 537: #ifdef DEBUG ! 538: print_derives(); ! 539: #endif ! 540: } ! 541: ! 542: free_derives() ! 543: { ! 544: FREE(derives[start_symbol]); ! 545: FREE(derives); ! 546: } ! 547: ! 548: #ifdef DEBUG ! 549: print_derives() ! 550: { ! 551: register int i; ! 552: register short *sp; ! 553: ! 554: printf("\nDERIVES\n\n"); ! 555: ! 556: for (i = start_symbol; i < nsyms; i++) ! 557: { ! 558: printf("%s derives ", symbol_name[i]); ! 559: for (sp = derives[i]; *sp >= 0; sp++) ! 560: { ! 561: printf(" %d", *sp); ! 562: } ! 563: putchar('\n'); ! 564: } ! 565: ! 566: putchar('\n'); ! 567: } ! 568: #endif ! 569: ! 570: ! 571: set_nullable() ! 572: { ! 573: register int i, j; ! 574: register int empty; ! 575: int done; ! 576: ! 577: nullable = MALLOC(nsyms); ! 578: if (nullable == 0) no_space(); ! 579: ! 580: for (i = 0; i < nsyms; ++i) ! 581: nullable[i] = 0; ! 582: ! 583: done = 0; ! 584: while (!done) ! 585: { ! 586: done = 1; ! 587: for (i = 1; i < nitems; i++) ! 588: { ! 589: empty = 1; ! 590: while ((j = ritem[i]) >= 0) ! 591: { ! 592: if (!nullable[j]) ! 593: empty = 0; ! 594: ++i; ! 595: } ! 596: if (empty) ! 597: { ! 598: j = rlhs[-j]; ! 599: if (!nullable[j]) ! 600: { ! 601: nullable[j] = 1; ! 602: done = 0; ! 603: } ! 604: } ! 605: } ! 606: } ! 607: ! 608: #ifdef DEBUG ! 609: for (i = 0; i < nsyms; i++) ! 610: { ! 611: if (nullable[i]) ! 612: printf("%s is nullable\n", symbol_name[i]); ! 613: else ! 614: printf("%s is not nullable\n", symbol_name[i]); ! 615: } ! 616: #endif ! 617: } ! 618: ! 619: ! 620: free_nullable() ! 621: { ! 622: FREE(nullable); ! 623: } ! 624: ! 625: ! 626: lr0() ! 627: { ! 628: set_derives(); ! 629: set_nullable(); ! 630: generate_states(); ! 631: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.