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