00001
00002 #include "defs.h"
00003
00004 extern short *itemset;
00005 extern short *itemsetend;
00006 extern unsigned *ruleset;
00007
00008 int nstates;
00009 core *first_state;
00010 shifts *first_shift;
00011 reductions *first_reduction;
00012
00013 int get_state();
00014 core *new_state();
00015
00016 static core **state_set;
00017 static core *this_state;
00018 static core *last_state;
00019 static shifts *last_shift;
00020 static reductions *last_reduction;
00021
00022 static int nshifts;
00023 static short *shift_symbol;
00024
00025 static short *redset;
00026 static short *shiftset;
00027
00028 static short **kernel_base;
00029 static short **kernel_end;
00030 static short *kernel_items;
00031
00032
00033 allocate_itemsets()
00034 {
00035 register short *itemp;
00036 register short *item_end;
00037 register int symbol;
00038 register int i;
00039 register int count;
00040 register int max;
00041 register short *symbol_count;
00042
00043 count = 0;
00044 symbol_count = NEW2(nsyms, short);
00045
00046 item_end = ritem + nitems;
00047 for (itemp = ritem; itemp < item_end; itemp++)
00048 {
00049 symbol = *itemp;
00050 if (symbol >= 0)
00051 {
00052 count++;
00053 symbol_count[symbol]++;
00054 }
00055 }
00056
00057 kernel_base = NEW2(nsyms, short *);
00058 kernel_items = NEW2(count, short);
00059
00060 count = 0;
00061 max = 0;
00062 for (i = 0; i < nsyms; i++)
00063 {
00064 kernel_base[i] = kernel_items + count;
00065 count += symbol_count[i];
00066 if (max < symbol_count[i])
00067 max = symbol_count[i];
00068 }
00069
00070 shift_symbol = symbol_count;
00071 kernel_end = NEW2(nsyms, short *);
00072 }
00073
00074
00075 allocate_storage()
00076 {
00077 allocate_itemsets();
00078 shiftset = NEW2(nsyms, short);
00079 redset = NEW2(nrules + 1, short);
00080 state_set = NEW2(nitems, core *);
00081 }
00082
00083
00084 append_states()
00085 {
00086 register int i;
00087 register int j;
00088 register int symbol;
00089
00090 #ifdef TRACE
00091 fprintf(stderr, "Entering append_states()\n");
00092 #endif
00093 for (i = 1; i < nshifts; i++)
00094 {
00095 symbol = shift_symbol[i];
00096 j = i;
00097 while (j > 0 && shift_symbol[j - 1] > symbol)
00098 {
00099 shift_symbol[j] = shift_symbol[j - 1];
00100 j--;
00101 }
00102 shift_symbol[j] = symbol;
00103 }
00104
00105 for (i = 0; i < nshifts; i++)
00106 {
00107 symbol = shift_symbol[i];
00108 shiftset[i] = get_state(symbol);
00109 }
00110 }
00111
00112
00113 free_storage()
00114 {
00115 FREE(shift_symbol);
00116 FREE(redset);
00117 FREE(shiftset);
00118 FREE(kernel_base);
00119 FREE(kernel_end);
00120 FREE(kernel_items);
00121 FREE(state_set);
00122 }
00123
00124
00125
00126 generate_states()
00127 {
00128 allocate_storage();
00129 itemset = NEW2(nitems, short);
00130 ruleset = NEW2(WORDSIZE(nrules), unsigned);
00131 set_first_derives();
00132 initialize_states();
00133
00134 while (this_state)
00135 {
00136 closure(this_state->items, this_state->nitems);
00137 save_reductions();
00138 new_itemsets();
00139 append_states();
00140
00141 if (nshifts > 0)
00142 save_shifts();
00143
00144 this_state = this_state->next;
00145 }
00146
00147 finalize_closure();
00148 free_storage();
00149 }
00150
00151
00152
00153 int
00154 get_state(symbol)
00155 int symbol;
00156 {
00157 register int key;
00158 register short *isp1;
00159 register short *isp2;
00160 register short *iend;
00161 register core *sp;
00162 register int found;
00163 register int n;
00164
00165 #ifdef TRACE
00166 fprintf(stderr, "Entering get_state(%d)\n", symbol);
00167 #endif
00168
00169 isp1 = kernel_base[symbol];
00170 iend = kernel_end[symbol];
00171 n = iend - isp1;
00172
00173 key = *isp1;
00174 assert(0 <= key && key < nitems);
00175 sp = state_set[key];
00176 if (sp)
00177 {
00178 found = 0;
00179 while (!found)
00180 {
00181 if (sp->nitems == n)
00182 {
00183 found = 1;
00184 isp1 = kernel_base[symbol];
00185 isp2 = sp->items;
00186
00187 while (found && isp1 < iend)
00188 {
00189 if (*isp1++ != *isp2++)
00190 found = 0;
00191 }
00192 }
00193
00194 if (!found)
00195 {
00196 if (sp->link)
00197 {
00198 sp = sp->link;
00199 }
00200 else
00201 {
00202 sp = sp->link = new_state(symbol);
00203 found = 1;
00204 }
00205 }
00206 }
00207 }
00208 else
00209 {
00210 state_set[key] = sp = new_state(symbol);
00211 }
00212
00213 return (sp->number);
00214 }
00215
00216
00217
00218 initialize_states()
00219 {
00220 register int i;
00221 register short *start_derives;
00222 register core *p;
00223
00224 start_derives = derives[start_symbol];
00225 for (i = 0; start_derives[i] >= 0; ++i)
00226 continue;
00227
00228 p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
00229 if (p == 0) no_space();
00230
00231 p->next = 0;
00232 p->link = 0;
00233 p->number = 0;
00234 p->accessing_symbol = 0;
00235 p->nitems = i;
00236
00237 for (i = 0; start_derives[i] >= 0; ++i)
00238 p->items[i] = rrhs[start_derives[i]];
00239
00240 first_state = last_state = this_state = p;
00241 nstates = 1;
00242 }
00243
00244
00245 new_itemsets()
00246 {
00247 register int i;
00248 register int shiftcount;
00249 register short *isp;
00250 register short *ksp;
00251 register int symbol;
00252
00253 for (i = 0; i < nsyms; i++)
00254 kernel_end[i] = 0;
00255
00256 shiftcount = 0;
00257 isp = itemset;
00258 while (isp < itemsetend)
00259 {
00260 i = *isp++;
00261 symbol = ritem[i];
00262 if (symbol > 0)
00263 {
00264 ksp = kernel_end[symbol];
00265 if (!ksp)
00266 {
00267 shift_symbol[shiftcount++] = symbol;
00268 ksp = kernel_base[symbol];
00269 }
00270
00271 *ksp++ = i + 1;
00272 kernel_end[symbol] = ksp;
00273 }
00274 }
00275
00276 nshifts = shiftcount;
00277 }
00278
00279
00280
00281 core *
00282 new_state(symbol)
00283 int symbol;
00284 {
00285 register int n;
00286 register core *p;
00287 register short *isp1;
00288 register short *isp2;
00289 register short *iend;
00290
00291 #ifdef TRACE
00292 fprintf(stderr, "Entering new_state(%d)\n", symbol);
00293 #endif
00294
00295 if (nstates >= MAXSHORT)
00296 fatal("too many states");
00297
00298 isp1 = kernel_base[symbol];
00299 iend = kernel_end[symbol];
00300 n = iend - isp1;
00301
00302 p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
00303 p->accessing_symbol = symbol;
00304 p->number = nstates;
00305 p->nitems = n;
00306
00307 isp2 = p->items;
00308 while (isp1 < iend)
00309 *isp2++ = *isp1++;
00310
00311 last_state->next = p;
00312 last_state = p;
00313
00314 nstates++;
00315
00316 return (p);
00317 }
00318
00319
00320
00321
00322 show_cores()
00323 {
00324 core *p;
00325 int i, j, k, n;
00326 int itemno;
00327
00328 k = 0;
00329 for (p = first_state; p; ++k, p = p->next)
00330 {
00331 if (k) printf("\n");
00332 printf("state %d, number = %d, accessing symbol = %s\n",
00333 k, p->number, symbol_name[p->accessing_symbol]);
00334 n = p->nitems;
00335 for (i = 0; i < n; ++i)
00336 {
00337 itemno = p->items[i];
00338 printf("%4d ", itemno);
00339 j = itemno;
00340 while (ritem[j] >= 0) ++j;
00341 printf("%s :", symbol_name[rlhs[-ritem[j]]]);
00342 j = rrhs[-ritem[j]];
00343 while (j < itemno)
00344 printf(" %s", symbol_name[ritem[j++]]);
00345 printf(" .");
00346 while (ritem[j] >= 0)
00347 printf(" %s", symbol_name[ritem[j++]]);
00348 printf("\n");
00349 fflush(stdout);
00350 }
00351 }
00352 }
00353
00354
00355
00356
00357 show_ritems()
00358 {
00359 int i;
00360
00361 for (i = 0; i < nitems; ++i)
00362 printf("ritem[%d] = %d\n", i, ritem[i]);
00363 }
00364
00365
00366
00367 show_rrhs()
00368 {
00369 int i;
00370
00371 for (i = 0; i < nrules; ++i)
00372 printf("rrhs[%d] = %d\n", i, rrhs[i]);
00373 }
00374
00375
00376
00377
00378 show_shifts()
00379 {
00380 shifts *p;
00381 int i, j, k;
00382
00383 k = 0;
00384 for (p = first_shift; p; ++k, p = p->next)
00385 {
00386 if (k) printf("\n");
00387 printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
00388 p->nshifts);
00389 j = p->nshifts;
00390 for (i = 0; i < j; ++i)
00391 printf("\t%d\n", p->shift[i]);
00392 }
00393 }
00394
00395
00396 save_shifts()
00397 {
00398 register shifts *p;
00399 register short *sp1;
00400 register short *sp2;
00401 register short *send;
00402
00403 p = (shifts *) allocate((unsigned) (sizeof(shifts) +
00404 (nshifts - 1) * sizeof(short)));
00405
00406 p->number = this_state->number;
00407 p->nshifts = nshifts;
00408
00409 sp1 = shiftset;
00410 sp2 = p->shift;
00411 send = shiftset + nshifts;
00412
00413 while (sp1 < send)
00414 *sp2++ = *sp1++;
00415
00416 if (last_shift)
00417 {
00418 last_shift->next = p;
00419 last_shift = p;
00420 }
00421 else
00422 {
00423 first_shift = p;
00424 last_shift = p;
00425 }
00426 }
00427
00428
00429
00430 save_reductions()
00431 {
00432 register short *isp;
00433 register short *rp1;
00434 register short *rp2;
00435 register int item;
00436 register int count;
00437 register reductions *p;
00438 register short *rend;
00439
00440 count = 0;
00441 for (isp = itemset; isp < itemsetend; isp++)
00442 {
00443 item = ritem[*isp];
00444 if (item < 0)
00445 {
00446 redset[count++] = -item;
00447 }
00448 }
00449
00450 if (count)
00451 {
00452 p = (reductions *) allocate((unsigned) (sizeof(reductions) +
00453 (count - 1) * sizeof(short)));
00454
00455 p->number = this_state->number;
00456 p->nreds = count;
00457
00458 rp1 = redset;
00459 rp2 = p->rules;
00460 rend = rp1 + count;
00461
00462 while (rp1 < rend)
00463 *rp2++ = *rp1++;
00464
00465 if (last_reduction)
00466 {
00467 last_reduction->next = p;
00468 last_reduction = p;
00469 }
00470 else
00471 {
00472 first_reduction = p;
00473 last_reduction = p;
00474 }
00475 }
00476 }
00477
00478
00479 set_derives()
00480 {
00481 register int i, k;
00482 register int lhs;
00483 register short *rules;
00484
00485 derives = NEW2(nsyms, short *);
00486 rules = NEW2(nvars + nrules, short);
00487
00488 k = 0;
00489 for (lhs = start_symbol; lhs < nsyms; lhs++)
00490 {
00491 derives[lhs] = rules + k;
00492 for (i = 0; i < nrules; i++)
00493 {
00494 if (rlhs[i] == lhs)
00495 {
00496 rules[k] = i;
00497 k++;
00498 }
00499 }
00500 rules[k] = -1;
00501 k++;
00502 }
00503
00504 #ifdef DEBUG
00505 print_derives();
00506 #endif
00507 }
00508
00509 free_derives()
00510 {
00511 FREE(derives[start_symbol]);
00512 FREE(derives);
00513 }
00514
00515 #ifdef DEBUG
00516 print_derives()
00517 {
00518 register int i;
00519 register short *sp;
00520
00521 printf("\nDERIVES\n\n");
00522
00523 for (i = start_symbol; i < nsyms; i++)
00524 {
00525 printf("%s derives ", symbol_name[i]);
00526 for (sp = derives[i]; *sp >= 0; sp++)
00527 {
00528 printf(" %d", *sp);
00529 }
00530 putchar('\n');
00531 }
00532
00533 putchar('\n');
00534 }
00535 #endif
00536
00537
00538 set_nullable()
00539 {
00540 register int i, j;
00541 register int empty;
00542 int done;
00543
00544 nullable = MALLOC(nsyms);
00545 if (nullable == 0) no_space();
00546
00547 for (i = 0; i < nsyms; ++i)
00548 nullable[i] = 0;
00549
00550 done = 0;
00551 while (!done)
00552 {
00553 done = 1;
00554 for (i = 1; i < nitems; i++)
00555 {
00556 empty = 1;
00557 while ((j = ritem[i]) >= 0)
00558 {
00559 if (!nullable[j])
00560 empty = 0;
00561 ++i;
00562 }
00563 if (empty)
00564 {
00565 j = rlhs[-j];
00566 if (!nullable[j])
00567 {
00568 nullable[j] = 1;
00569 done = 0;
00570 }
00571 }
00572 }
00573 }
00574
00575 #ifdef DEBUG
00576 for (i = 0; i < nsyms; i++)
00577 {
00578 if (nullable[i])
00579 printf("%s is nullable\n", symbol_name[i]);
00580 else
00581 printf("%s is not nullable\n", symbol_name[i]);
00582 }
00583 #endif
00584 }
00585
00586
00587 free_nullable()
00588 {
00589 FREE(nullable);
00590 }
00591
00592
00593 lr0()
00594 {
00595 set_derives();
00596 set_nullable();
00597 generate_states();
00598 }