1240517Sbapt/* $Id: lr0.c,v 1.13 2012/05/26 00:40:47 tom Exp $ */ 2234949Sbapt 3234949Sbapt#include "defs.h" 4234949Sbapt 5234949Sbaptstatic core *new_state(int symbol); 6234949Sbaptstatic Value_t get_state(int symbol); 7234949Sbaptstatic void allocate_itemsets(void); 8234949Sbaptstatic void allocate_storage(void); 9234949Sbaptstatic void append_states(void); 10234949Sbaptstatic void free_storage(void); 11234949Sbaptstatic void generate_states(void); 12234949Sbaptstatic void initialize_states(void); 13234949Sbaptstatic void new_itemsets(void); 14234949Sbaptstatic void save_reductions(void); 15234949Sbaptstatic void save_shifts(void); 16234949Sbaptstatic void set_derives(void); 17234949Sbaptstatic void set_nullable(void); 18234949Sbapt 19234949Sbaptint nstates; 20234949Sbaptcore *first_state; 21234949Sbaptshifts *first_shift; 22234949Sbaptreductions *first_reduction; 23234949Sbapt 24234949Sbaptstatic core **state_set; 25234949Sbaptstatic core *this_state; 26234949Sbaptstatic core *last_state; 27234949Sbaptstatic shifts *last_shift; 28234949Sbaptstatic reductions *last_reduction; 29234949Sbapt 30234949Sbaptstatic int nshifts; 31234949Sbaptstatic short *shift_symbol; 32234949Sbapt 33234949Sbaptstatic Value_t *redset; 34234949Sbaptstatic Value_t *shiftset; 35234949Sbapt 36234949Sbaptstatic Value_t **kernel_base; 37234949Sbaptstatic Value_t **kernel_end; 38234949Sbaptstatic Value_t *kernel_items; 39234949Sbapt 40234949Sbaptstatic void 41234949Sbaptallocate_itemsets(void) 42234949Sbapt{ 43234949Sbapt short *itemp; 44234949Sbapt short *item_end; 45234949Sbapt int symbol; 46234949Sbapt int i; 47234949Sbapt int count; 48234949Sbapt int max; 49234949Sbapt short *symbol_count; 50234949Sbapt 51234949Sbapt count = 0; 52234949Sbapt symbol_count = NEW2(nsyms, short); 53234949Sbapt 54234949Sbapt item_end = ritem + nitems; 55234949Sbapt for (itemp = ritem; itemp < item_end; itemp++) 56234949Sbapt { 57234949Sbapt symbol = *itemp; 58234949Sbapt if (symbol >= 0) 59234949Sbapt { 60234949Sbapt count++; 61234949Sbapt symbol_count[symbol]++; 62234949Sbapt } 63234949Sbapt } 64234949Sbapt 65234949Sbapt kernel_base = NEW2(nsyms, short *); 66234949Sbapt kernel_items = NEW2(count, short); 67234949Sbapt 68234949Sbapt count = 0; 69234949Sbapt max = 0; 70234949Sbapt for (i = 0; i < nsyms; i++) 71234949Sbapt { 72234949Sbapt kernel_base[i] = kernel_items + count; 73234949Sbapt count += symbol_count[i]; 74234949Sbapt if (max < symbol_count[i]) 75234949Sbapt max = symbol_count[i]; 76234949Sbapt } 77234949Sbapt 78234949Sbapt shift_symbol = symbol_count; 79234949Sbapt kernel_end = NEW2(nsyms, short *); 80234949Sbapt} 81234949Sbapt 82234949Sbaptstatic void 83234949Sbaptallocate_storage(void) 84234949Sbapt{ 85234949Sbapt allocate_itemsets(); 86234949Sbapt shiftset = NEW2(nsyms, short); 87234949Sbapt redset = NEW2(nrules + 1, short); 88234949Sbapt state_set = NEW2(nitems, core *); 89234949Sbapt} 90234949Sbapt 91234949Sbaptstatic void 92234949Sbaptappend_states(void) 93234949Sbapt{ 94234949Sbapt int i; 95234949Sbapt int j; 96234949Sbapt Value_t symbol; 97234949Sbapt 98234949Sbapt#ifdef TRACE 99234949Sbapt fprintf(stderr, "Entering append_states()\n"); 100234949Sbapt#endif 101234949Sbapt for (i = 1; i < nshifts; i++) 102234949Sbapt { 103234949Sbapt symbol = shift_symbol[i]; 104234949Sbapt j = i; 105234949Sbapt while (j > 0 && shift_symbol[j - 1] > symbol) 106234949Sbapt { 107234949Sbapt shift_symbol[j] = shift_symbol[j - 1]; 108234949Sbapt j--; 109234949Sbapt } 110234949Sbapt shift_symbol[j] = symbol; 111234949Sbapt } 112234949Sbapt 113234949Sbapt for (i = 0; i < nshifts; i++) 114234949Sbapt { 115234949Sbapt symbol = shift_symbol[i]; 116234949Sbapt shiftset[i] = get_state(symbol); 117234949Sbapt } 118234949Sbapt} 119234949Sbapt 120234949Sbaptstatic void 121234949Sbaptfree_storage(void) 122234949Sbapt{ 123234949Sbapt FREE(shift_symbol); 124234949Sbapt FREE(redset); 125234949Sbapt FREE(shiftset); 126234949Sbapt FREE(kernel_base); 127234949Sbapt FREE(kernel_end); 128234949Sbapt FREE(kernel_items); 129234949Sbapt FREE(state_set); 130234949Sbapt} 131234949Sbapt 132234949Sbaptstatic void 133234949Sbaptgenerate_states(void) 134234949Sbapt{ 135234949Sbapt allocate_storage(); 136234949Sbapt itemset = NEW2(nitems, short); 137234949Sbapt ruleset = NEW2(WORDSIZE(nrules), unsigned); 138234949Sbapt set_first_derives(); 139234949Sbapt initialize_states(); 140234949Sbapt 141234949Sbapt while (this_state) 142234949Sbapt { 143234949Sbapt closure(this_state->items, this_state->nitems); 144234949Sbapt save_reductions(); 145234949Sbapt new_itemsets(); 146234949Sbapt append_states(); 147234949Sbapt 148234949Sbapt if (nshifts > 0) 149234949Sbapt save_shifts(); 150234949Sbapt 151234949Sbapt this_state = this_state->next; 152234949Sbapt } 153234949Sbapt 154234949Sbapt free_storage(); 155234949Sbapt} 156234949Sbapt 157234949Sbaptstatic Value_t 158234949Sbaptget_state(int symbol) 159234949Sbapt{ 160234949Sbapt int key; 161234949Sbapt short *isp1; 162234949Sbapt short *isp2; 163234949Sbapt short *iend; 164234949Sbapt core *sp; 165234949Sbapt int found; 166234949Sbapt int n; 167234949Sbapt 168234949Sbapt#ifdef TRACE 169234949Sbapt fprintf(stderr, "Entering get_state(%d)\n", symbol); 170234949Sbapt#endif 171234949Sbapt 172234949Sbapt isp1 = kernel_base[symbol]; 173234949Sbapt iend = kernel_end[symbol]; 174234949Sbapt n = (int)(iend - isp1); 175234949Sbapt 176234949Sbapt key = *isp1; 177234949Sbapt assert(0 <= key && key < nitems); 178234949Sbapt sp = state_set[key]; 179234949Sbapt if (sp) 180234949Sbapt { 181234949Sbapt found = 0; 182234949Sbapt while (!found) 183234949Sbapt { 184234949Sbapt if (sp->nitems == n) 185234949Sbapt { 186234949Sbapt found = 1; 187234949Sbapt isp1 = kernel_base[symbol]; 188234949Sbapt isp2 = sp->items; 189234949Sbapt 190234949Sbapt while (found && isp1 < iend) 191234949Sbapt { 192234949Sbapt if (*isp1++ != *isp2++) 193234949Sbapt found = 0; 194234949Sbapt } 195234949Sbapt } 196234949Sbapt 197234949Sbapt if (!found) 198234949Sbapt { 199234949Sbapt if (sp->link) 200234949Sbapt { 201234949Sbapt sp = sp->link; 202234949Sbapt } 203234949Sbapt else 204234949Sbapt { 205234949Sbapt sp = sp->link = new_state(symbol); 206234949Sbapt found = 1; 207234949Sbapt } 208234949Sbapt } 209234949Sbapt } 210234949Sbapt } 211234949Sbapt else 212234949Sbapt { 213234949Sbapt state_set[key] = sp = new_state(symbol); 214234949Sbapt } 215234949Sbapt 216234949Sbapt return (sp->number); 217234949Sbapt} 218234949Sbapt 219234949Sbaptstatic void 220234949Sbaptinitialize_states(void) 221234949Sbapt{ 222234949Sbapt unsigned i; 223234949Sbapt short *start_derives; 224234949Sbapt core *p; 225234949Sbapt 226234949Sbapt start_derives = derives[start_symbol]; 227234949Sbapt for (i = 0; start_derives[i] >= 0; ++i) 228234949Sbapt continue; 229234949Sbapt 230234949Sbapt p = (core *)MALLOC(sizeof(core) + i * sizeof(short)); 231234949Sbapt NO_SPACE(p); 232234949Sbapt 233234949Sbapt p->next = 0; 234234949Sbapt p->link = 0; 235234949Sbapt p->number = 0; 236234949Sbapt p->accessing_symbol = 0; 237234949Sbapt p->nitems = (Value_t) i; 238234949Sbapt 239234949Sbapt for (i = 0; start_derives[i] >= 0; ++i) 240234949Sbapt p->items[i] = rrhs[start_derives[i]]; 241234949Sbapt 242234949Sbapt first_state = last_state = this_state = p; 243234949Sbapt nstates = 1; 244234949Sbapt} 245234949Sbapt 246234949Sbaptstatic void 247234949Sbaptnew_itemsets(void) 248234949Sbapt{ 249234949Sbapt Value_t i; 250234949Sbapt int shiftcount; 251234949Sbapt short *isp; 252234949Sbapt short *ksp; 253234949Sbapt Value_t symbol; 254234949Sbapt 255234949Sbapt for (i = 0; i < nsyms; i++) 256234949Sbapt kernel_end[i] = 0; 257234949Sbapt 258234949Sbapt shiftcount = 0; 259234949Sbapt isp = itemset; 260234949Sbapt while (isp < itemsetend) 261234949Sbapt { 262234949Sbapt i = *isp++; 263234949Sbapt symbol = ritem[i]; 264234949Sbapt if (symbol > 0) 265234949Sbapt { 266234949Sbapt ksp = kernel_end[symbol]; 267234949Sbapt if (!ksp) 268234949Sbapt { 269234949Sbapt shift_symbol[shiftcount++] = symbol; 270234949Sbapt ksp = kernel_base[symbol]; 271234949Sbapt } 272234949Sbapt 273234949Sbapt *ksp++ = (Value_t) (i + 1); 274234949Sbapt kernel_end[symbol] = ksp; 275234949Sbapt } 276234949Sbapt } 277234949Sbapt 278234949Sbapt nshifts = shiftcount; 279234949Sbapt} 280234949Sbapt 281234949Sbaptstatic core * 282234949Sbaptnew_state(int symbol) 283234949Sbapt{ 284234949Sbapt unsigned n; 285234949Sbapt core *p; 286234949Sbapt short *isp1; 287234949Sbapt short *isp2; 288234949Sbapt short *iend; 289234949Sbapt 290234949Sbapt#ifdef TRACE 291234949Sbapt fprintf(stderr, "Entering new_state(%d)\n", symbol); 292234949Sbapt#endif 293234949Sbapt 294234949Sbapt if (nstates >= MAXSHORT) 295234949Sbapt fatal("too many states"); 296234949Sbapt 297234949Sbapt isp1 = kernel_base[symbol]; 298234949Sbapt iend = kernel_end[symbol]; 299234949Sbapt n = (unsigned)(iend - isp1); 300234949Sbapt 301234949Sbapt p = (core *)allocate((sizeof(core) + (n - 1) * sizeof(short))); 302234949Sbapt p->accessing_symbol = (Value_t) symbol; 303234949Sbapt p->number = (Value_t) nstates; 304234949Sbapt p->nitems = (Value_t) n; 305234949Sbapt 306234949Sbapt isp2 = p->items; 307234949Sbapt while (isp1 < iend) 308234949Sbapt *isp2++ = *isp1++; 309234949Sbapt 310234949Sbapt last_state->next = p; 311234949Sbapt last_state = p; 312234949Sbapt 313234949Sbapt nstates++; 314234949Sbapt 315234949Sbapt return (p); 316234949Sbapt} 317234949Sbapt 318234949Sbapt/* show_cores is used for debugging */ 319234949Sbapt 320234949Sbaptvoid 321234949Sbaptshow_cores(void) 322234949Sbapt{ 323234949Sbapt core *p; 324234949Sbapt int i, j, k, n; 325234949Sbapt int itemno; 326234949Sbapt 327234949Sbapt k = 0; 328234949Sbapt for (p = first_state; p; ++k, p = p->next) 329234949Sbapt { 330234949Sbapt if (k) 331234949Sbapt printf("\n"); 332234949Sbapt printf("state %d, number = %d, accessing symbol = %s\n", 333234949Sbapt k, p->number, symbol_name[p->accessing_symbol]); 334234949Sbapt n = p->nitems; 335234949Sbapt for (i = 0; i < n; ++i) 336234949Sbapt { 337234949Sbapt itemno = p->items[i]; 338234949Sbapt printf("%4d ", itemno); 339234949Sbapt j = itemno; 340234949Sbapt while (ritem[j] >= 0) 341234949Sbapt ++j; 342234949Sbapt printf("%s :", symbol_name[rlhs[-ritem[j]]]); 343234949Sbapt j = rrhs[-ritem[j]]; 344234949Sbapt while (j < itemno) 345234949Sbapt printf(" %s", symbol_name[ritem[j++]]); 346234949Sbapt printf(" ."); 347234949Sbapt while (ritem[j] >= 0) 348234949Sbapt printf(" %s", symbol_name[ritem[j++]]); 349234949Sbapt printf("\n"); 350234949Sbapt fflush(stdout); 351234949Sbapt } 352234949Sbapt } 353234949Sbapt} 354234949Sbapt 355234949Sbapt/* show_ritems is used for debugging */ 356234949Sbapt 357234949Sbaptvoid 358234949Sbaptshow_ritems(void) 359234949Sbapt{ 360234949Sbapt int i; 361234949Sbapt 362234949Sbapt for (i = 0; i < nitems; ++i) 363234949Sbapt printf("ritem[%d] = %d\n", i, ritem[i]); 364234949Sbapt} 365234949Sbapt 366234949Sbapt/* show_rrhs is used for debugging */ 367234949Sbaptvoid 368234949Sbaptshow_rrhs(void) 369234949Sbapt{ 370234949Sbapt int i; 371234949Sbapt 372234949Sbapt for (i = 0; i < nrules; ++i) 373234949Sbapt printf("rrhs[%d] = %d\n", i, rrhs[i]); 374234949Sbapt} 375234949Sbapt 376234949Sbapt/* show_shifts is used for debugging */ 377234949Sbapt 378234949Sbaptvoid 379234949Sbaptshow_shifts(void) 380234949Sbapt{ 381234949Sbapt shifts *p; 382234949Sbapt int i, j, k; 383234949Sbapt 384234949Sbapt k = 0; 385234949Sbapt for (p = first_shift; p; ++k, p = p->next) 386234949Sbapt { 387234949Sbapt if (k) 388234949Sbapt printf("\n"); 389234949Sbapt printf("shift %d, number = %d, nshifts = %d\n", k, p->number, 390234949Sbapt p->nshifts); 391234949Sbapt j = p->nshifts; 392234949Sbapt for (i = 0; i < j; ++i) 393234949Sbapt printf("\t%d\n", p->shift[i]); 394234949Sbapt } 395234949Sbapt} 396234949Sbapt 397234949Sbaptstatic void 398234949Sbaptsave_shifts(void) 399234949Sbapt{ 400234949Sbapt shifts *p; 401234949Sbapt short *sp1; 402234949Sbapt short *sp2; 403234949Sbapt short *send; 404234949Sbapt 405234949Sbapt p = (shifts *)allocate((sizeof(shifts) + 406234949Sbapt (unsigned)(nshifts - 1) * sizeof(short))); 407234949Sbapt 408234949Sbapt p->number = this_state->number; 409234949Sbapt p->nshifts = (Value_t) nshifts; 410234949Sbapt 411234949Sbapt sp1 = shiftset; 412234949Sbapt sp2 = p->shift; 413234949Sbapt send = shiftset + nshifts; 414234949Sbapt 415234949Sbapt while (sp1 < send) 416234949Sbapt *sp2++ = *sp1++; 417234949Sbapt 418234949Sbapt if (last_shift) 419234949Sbapt { 420234949Sbapt last_shift->next = p; 421234949Sbapt last_shift = p; 422234949Sbapt } 423234949Sbapt else 424234949Sbapt { 425234949Sbapt first_shift = p; 426234949Sbapt last_shift = p; 427234949Sbapt } 428234949Sbapt} 429234949Sbapt 430234949Sbaptstatic void 431234949Sbaptsave_reductions(void) 432234949Sbapt{ 433234949Sbapt short *isp; 434234949Sbapt short *rp1; 435234949Sbapt short *rp2; 436234949Sbapt int item; 437234949Sbapt Value_t count; 438234949Sbapt reductions *p; 439234949Sbapt short *rend; 440234949Sbapt 441234949Sbapt count = 0; 442234949Sbapt for (isp = itemset; isp < itemsetend; isp++) 443234949Sbapt { 444234949Sbapt item = ritem[*isp]; 445234949Sbapt if (item < 0) 446234949Sbapt { 447234949Sbapt redset[count++] = (Value_t) - item; 448234949Sbapt } 449234949Sbapt } 450234949Sbapt 451234949Sbapt if (count) 452234949Sbapt { 453234949Sbapt p = (reductions *)allocate((sizeof(reductions) + 454234949Sbapt (unsigned)(count - 1) * 455234949Sbapt sizeof(short))); 456234949Sbapt 457234949Sbapt p->number = this_state->number; 458234949Sbapt p->nreds = count; 459234949Sbapt 460234949Sbapt rp1 = redset; 461234949Sbapt rp2 = p->rules; 462234949Sbapt rend = rp1 + count; 463234949Sbapt 464234949Sbapt while (rp1 < rend) 465234949Sbapt *rp2++ = *rp1++; 466234949Sbapt 467234949Sbapt if (last_reduction) 468234949Sbapt { 469234949Sbapt last_reduction->next = p; 470234949Sbapt last_reduction = p; 471234949Sbapt } 472234949Sbapt else 473234949Sbapt { 474234949Sbapt first_reduction = p; 475234949Sbapt last_reduction = p; 476234949Sbapt } 477234949Sbapt } 478234949Sbapt} 479234949Sbapt 480234949Sbaptstatic void 481234949Sbaptset_derives(void) 482234949Sbapt{ 483234949Sbapt Value_t i, k; 484234949Sbapt int lhs; 485234949Sbapt short *rules; 486234949Sbapt 487234949Sbapt derives = NEW2(nsyms, short *); 488234949Sbapt rules = NEW2(nvars + nrules, short); 489234949Sbapt 490234949Sbapt k = 0; 491234949Sbapt for (lhs = start_symbol; lhs < nsyms; lhs++) 492234949Sbapt { 493234949Sbapt derives[lhs] = rules + k; 494234949Sbapt for (i = 0; i < nrules; i++) 495234949Sbapt { 496234949Sbapt if (rlhs[i] == lhs) 497234949Sbapt { 498234949Sbapt rules[k] = i; 499234949Sbapt k++; 500234949Sbapt } 501234949Sbapt } 502234949Sbapt rules[k] = -1; 503234949Sbapt k++; 504234949Sbapt } 505234949Sbapt 506234949Sbapt#ifdef DEBUG 507234949Sbapt print_derives(); 508234949Sbapt#endif 509234949Sbapt} 510234949Sbapt 511234949Sbapt#ifdef DEBUG 512234949Sbaptvoid 513234949Sbaptprint_derives(void) 514234949Sbapt{ 515234949Sbapt int i; 516234949Sbapt short *sp; 517234949Sbapt 518234949Sbapt printf("\nDERIVES\n\n"); 519234949Sbapt 520234949Sbapt for (i = start_symbol; i < nsyms; i++) 521234949Sbapt { 522234949Sbapt printf("%s derives ", symbol_name[i]); 523234949Sbapt for (sp = derives[i]; *sp >= 0; sp++) 524234949Sbapt { 525234949Sbapt printf(" %d", *sp); 526234949Sbapt } 527234949Sbapt putchar('\n'); 528234949Sbapt } 529234949Sbapt 530234949Sbapt putchar('\n'); 531234949Sbapt} 532234949Sbapt#endif 533234949Sbapt 534234949Sbaptstatic void 535234949Sbaptset_nullable(void) 536234949Sbapt{ 537234949Sbapt int i, j; 538234949Sbapt int empty; 539234949Sbapt int done_flag; 540234949Sbapt 541240517Sbapt nullable = TMALLOC(char, nsyms); 542234949Sbapt NO_SPACE(nullable); 543234949Sbapt 544234949Sbapt for (i = 0; i < nsyms; ++i) 545234949Sbapt nullable[i] = 0; 546234949Sbapt 547234949Sbapt done_flag = 0; 548234949Sbapt while (!done_flag) 549234949Sbapt { 550234949Sbapt done_flag = 1; 551234949Sbapt for (i = 1; i < nitems; i++) 552234949Sbapt { 553234949Sbapt empty = 1; 554234949Sbapt while ((j = ritem[i]) >= 0) 555234949Sbapt { 556234949Sbapt if (!nullable[j]) 557234949Sbapt empty = 0; 558234949Sbapt ++i; 559234949Sbapt } 560234949Sbapt if (empty) 561234949Sbapt { 562234949Sbapt j = rlhs[-j]; 563234949Sbapt if (!nullable[j]) 564234949Sbapt { 565234949Sbapt nullable[j] = 1; 566234949Sbapt done_flag = 0; 567234949Sbapt } 568234949Sbapt } 569234949Sbapt } 570234949Sbapt } 571234949Sbapt 572234949Sbapt#ifdef DEBUG 573234949Sbapt for (i = 0; i < nsyms; i++) 574234949Sbapt { 575234949Sbapt if (nullable[i]) 576234949Sbapt printf("%s is nullable\n", symbol_name[i]); 577234949Sbapt else 578234949Sbapt printf("%s is not nullable\n", symbol_name[i]); 579234949Sbapt } 580234949Sbapt#endif 581234949Sbapt} 582234949Sbapt 583234949Sbaptvoid 584234949Sbaptlr0(void) 585234949Sbapt{ 586234949Sbapt set_derives(); 587234949Sbapt set_nullable(); 588234949Sbapt generate_states(); 589234949Sbapt} 590234949Sbapt 591234949Sbapt#ifdef NO_LEAKS 592234949Sbaptvoid 593234949Sbaptlr0_leaks(void) 594234949Sbapt{ 595234949Sbapt DO_FREE(derives[start_symbol]); 596234949Sbapt DO_FREE(derives); 597234949Sbapt DO_FREE(nullable); 598234949Sbapt} 599234949Sbapt#endif 600