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