lr0.c

Go to the documentation of this file.
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 /* show_cores is used for debugging */
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 /* show_ritems is used for debugging */
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 /* show_rrhs is used for debugging */
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 /* show_shifts is used for debugging */
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 }

Generated on Fri Apr 14 22:56:45 2006 for minix by  doxygen 1.4.6