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