lalr.c

Go to the documentation of this file.
00001 #include "defs.h"
00002 
00003 typedef
00004   struct shorts
00005     {
00006       struct shorts *next;
00007       short value;
00008     }
00009   shorts;
00010 
00011 int tokensetsize;
00012 short *lookaheads;
00013 short *LAruleno;
00014 unsigned *LA;
00015 short *accessing_symbol;
00016 core **state_table;
00017 shifts **shift_table;
00018 reductions **reduction_table;
00019 short *goto_map;
00020 short *from_state;
00021 short *to_state;
00022 
00023 short **transpose();
00024 
00025 static int infinity;
00026 static int maxrhs;
00027 static int ngotos;
00028 static unsigned *F;
00029 static short **includes;
00030 static shorts **lookback;
00031 static short **R;
00032 static short *INDEX;
00033 static short *VERTICES;
00034 static int top;
00035 
00036 
00037 lalr()
00038 {
00039     tokensetsize = WORDSIZE(ntokens);
00040 
00041     set_state_table();
00042     set_accessing_symbol();
00043     set_shift_table();
00044     set_reduction_table();
00045     set_maxrhs();
00046     initialize_LA();
00047     set_goto_map();
00048     initialize_F();
00049     build_relations();
00050     compute_FOLLOWS();
00051     compute_lookaheads();
00052 }
00053 
00054 
00055 
00056 set_state_table()
00057 {
00058     register core *sp;
00059 
00060     state_table = NEW2(nstates, core *);
00061     for (sp = first_state; sp; sp = sp->next)
00062         state_table[sp->number] = sp;
00063 }
00064 
00065 
00066 
00067 set_accessing_symbol()
00068 {
00069     register core *sp;
00070 
00071     accessing_symbol = NEW2(nstates, short);
00072     for (sp = first_state; sp; sp = sp->next)
00073         accessing_symbol[sp->number] = sp->accessing_symbol;
00074 }
00075 
00076 
00077 
00078 set_shift_table()
00079 {
00080     register shifts *sp;
00081 
00082     shift_table = NEW2(nstates, shifts *);
00083     for (sp = first_shift; sp; sp = sp->next)
00084         shift_table[sp->number] = sp;
00085 }
00086 
00087 
00088 
00089 set_reduction_table()
00090 {
00091     register reductions *rp;
00092 
00093     reduction_table = NEW2(nstates, reductions *);
00094     for (rp = first_reduction; rp; rp = rp->next)
00095         reduction_table[rp->number] = rp;
00096 }
00097 
00098 
00099 
00100 set_maxrhs()
00101 {
00102   register short *itemp;
00103   register short *item_end;
00104   register int length;
00105   register int max;
00106 
00107   length = 0;
00108   max = 0;
00109   item_end = ritem + nitems;
00110   for (itemp = ritem; itemp < item_end; itemp++)
00111     {
00112       if (*itemp >= 0)
00113         {
00114           length++;
00115         }
00116       else
00117         {
00118           if (length > max) max = length;
00119           length = 0;
00120         }
00121     }
00122 
00123   maxrhs = max;
00124 }
00125 
00126 
00127 
00128 initialize_LA()
00129 {
00130   register int i, j, k;
00131   register reductions *rp;
00132 
00133   lookaheads = NEW2(nstates + 1, short);
00134 
00135   k = 0;
00136   for (i = 0; i < nstates; i++)
00137     {
00138       lookaheads[i] = k;
00139       rp = reduction_table[i];
00140       if (rp)
00141         k += rp->nreds;
00142     }
00143   lookaheads[nstates] = k;
00144 
00145   LA = NEW2(k * tokensetsize, unsigned);
00146   LAruleno = NEW2(k, short);
00147   lookback = NEW2(k, shorts *);
00148 
00149   k = 0;
00150   for (i = 0; i < nstates; i++)
00151     {
00152       rp = reduction_table[i];
00153       if (rp)
00154         {
00155           for (j = 0; j < rp->nreds; j++)
00156             {
00157               LAruleno[k] = rp->rules[j];
00158               k++;
00159             }
00160         }
00161     }
00162 }
00163 
00164 
00165 set_goto_map()
00166 {
00167   register shifts *sp;
00168   register int i;
00169   register int symbol;
00170   register int k;
00171   register short *temp_map;
00172   register int state2;
00173   register int state1;
00174 
00175   goto_map = NEW2(nvars + 1, short) - ntokens;
00176   temp_map = NEW2(nvars + 1, short) - ntokens;
00177 
00178   ngotos = 0;
00179   for (sp = first_shift; sp; sp = sp->next)
00180     {
00181       for (i = sp->nshifts - 1; i >= 0; i--)
00182         {
00183           symbol = accessing_symbol[sp->shift[i]];
00184 
00185           if (ISTOKEN(symbol)) break;
00186 
00187           if (ngotos == MAXSHORT)
00188             fatal("too many gotos");
00189 
00190           ngotos++;
00191           goto_map[symbol]++;
00192         }
00193     }
00194 
00195   k = 0;
00196   for (i = ntokens; i < nsyms; i++)
00197     {
00198       temp_map[i] = k;
00199       k += goto_map[i];
00200     }
00201 
00202   for (i = ntokens; i < nsyms; i++)
00203     goto_map[i] = temp_map[i];
00204 
00205   goto_map[nsyms] = ngotos;
00206   temp_map[nsyms] = ngotos;
00207 
00208   from_state = NEW2(ngotos, short);
00209   to_state = NEW2(ngotos, short);
00210 
00211   for (sp = first_shift; sp; sp = sp->next)
00212     {
00213       state1 = sp->number;
00214       for (i = sp->nshifts - 1; i >= 0; i--)
00215         {
00216           state2 = sp->shift[i];
00217           symbol = accessing_symbol[state2];
00218 
00219           if (ISTOKEN(symbol)) break;
00220 
00221           k = temp_map[symbol]++;
00222           from_state[k] = state1;
00223           to_state[k] = state2;
00224         }
00225     }
00226 
00227   FREE(temp_map + ntokens);
00228 }
00229 
00230 
00231 
00232 /*  Map_goto maps a state/symbol pair into its numeric representation.  */
00233 
00234 int
00235 map_goto(state, symbol)
00236 int state;
00237 int symbol;
00238 {
00239     register int high;
00240     register int low;
00241     register int middle;
00242     register int s;
00243 
00244     low = goto_map[symbol];
00245     high = goto_map[symbol + 1];
00246 
00247     for (;;)
00248     {
00249         assert(low <= high);
00250         middle = (low + high) >> 1;
00251         s = from_state[middle];
00252         if (s == state)
00253             return (middle);
00254         else if (s < state)
00255             low = middle + 1;
00256         else
00257             high = middle - 1;
00258     }
00259 }
00260 
00261 
00262 
00263 initialize_F()
00264 {
00265   register int i;
00266   register int j;
00267   register int k;
00268   register shifts *sp;
00269   register short *edge;
00270   register unsigned *rowp;
00271   register short *rp;
00272   register short **reads;
00273   register int nedges;
00274   register int stateno;
00275   register int symbol;
00276   register int nwords;
00277 
00278   nwords = ngotos * tokensetsize;
00279   F = NEW2(nwords, unsigned);
00280 
00281   reads = NEW2(ngotos, short *);
00282   edge = NEW2(ngotos + 1, short);
00283   nedges = 0;
00284 
00285   rowp = F;
00286   for (i = 0; i < ngotos; i++)
00287     {
00288       stateno = to_state[i];
00289       sp = shift_table[stateno];
00290 
00291       if (sp)
00292         {
00293           k = sp->nshifts;
00294 
00295           for (j = 0; j < k; j++)
00296             {
00297               symbol = accessing_symbol[sp->shift[j]];
00298               if (ISVAR(symbol))
00299                 break;
00300               SETBIT(rowp, symbol);
00301             }
00302 
00303           for (; j < k; j++)
00304             {
00305               symbol = accessing_symbol[sp->shift[j]];
00306               if (nullable[symbol])
00307                 edge[nedges++] = map_goto(stateno, symbol);
00308             }
00309         
00310           if (nedges)
00311             {
00312               reads[i] = rp = NEW2(nedges + 1, short);
00313 
00314               for (j = 0; j < nedges; j++)
00315                 rp[j] = edge[j];
00316 
00317               rp[nedges] = -1;
00318               nedges = 0;
00319             }
00320         }
00321 
00322       rowp += tokensetsize;
00323     }
00324 
00325   SETBIT(F, 0);
00326   digraph(reads);
00327 
00328   for (i = 0; i < ngotos; i++)
00329     {
00330       if (reads[i])
00331         FREE(reads[i]);
00332     }
00333 
00334   FREE(reads);
00335   FREE(edge);
00336 }
00337 
00338 
00339 
00340 build_relations()
00341 {
00342   register int i;
00343   register int j;
00344   register int k;
00345   register short *rulep;
00346   register short *rp;
00347   register shifts *sp;
00348   register int length;
00349   register int nedges;
00350   register int done;
00351   register int state1;
00352   register int stateno;
00353   register int symbol1;
00354   register int symbol2;
00355   register short *shortp;
00356   register short *edge;
00357   register short *states;
00358   register short **new_includes;
00359 
00360   includes = NEW2(ngotos, short *);
00361   edge = NEW2(ngotos + 1, short);
00362   states = NEW2(maxrhs + 1, short);
00363 
00364   for (i = 0; i < ngotos; i++)
00365     {
00366       nedges = 0;
00367       state1 = from_state[i];
00368       symbol1 = accessing_symbol[to_state[i]];
00369 
00370       for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
00371         {
00372           length = 1;
00373           states[0] = state1;
00374           stateno = state1;
00375 
00376           for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
00377             {
00378               symbol2 = *rp;
00379               sp = shift_table[stateno];
00380               k = sp->nshifts;
00381 
00382               for (j = 0; j < k; j++)
00383                 {
00384                   stateno = sp->shift[j];
00385                   if (accessing_symbol[stateno] == symbol2) break;
00386                 }
00387 
00388               states[length++] = stateno;
00389             }
00390 
00391           add_lookback_edge(stateno, *rulep, i);
00392 
00393           length--;
00394           done = 0;
00395           while (!done)
00396             {
00397               done = 1;
00398               rp--;
00399               if (ISVAR(*rp))
00400                 {
00401                   stateno = states[--length];
00402                   edge[nedges++] = map_goto(stateno, *rp);
00403                   if (nullable[*rp] && length > 0) done = 0;
00404                 }
00405             }
00406         }
00407 
00408       if (nedges)
00409         {
00410           includes[i] = shortp = NEW2(nedges + 1, short);
00411           for (j = 0; j < nedges; j++)
00412             shortp[j] = edge[j];
00413           shortp[nedges] = -1;
00414         }
00415     }
00416 
00417   new_includes = transpose(includes, ngotos);
00418 
00419   for (i = 0; i < ngotos; i++)
00420     if (includes[i])
00421       FREE(includes[i]);
00422 
00423   FREE(includes);
00424 
00425   includes = new_includes;
00426 
00427   FREE(edge);
00428   FREE(states);
00429 }
00430 
00431 
00432 add_lookback_edge(stateno, ruleno, gotono)
00433 int stateno, ruleno, gotono;
00434 {
00435     register int i, k;
00436     register int found;
00437     register shorts *sp;
00438 
00439     i = lookaheads[stateno];
00440     k = lookaheads[stateno + 1];
00441     found = 0;
00442     while (!found && i < k)
00443     {
00444         if (LAruleno[i] == ruleno)
00445             found = 1;
00446         else
00447             ++i;
00448     }
00449     assert(found);
00450 
00451     sp = NEW(shorts);
00452     sp->next = lookback[i];
00453     sp->value = gotono;
00454     lookback[i] = sp;
00455 }
00456 
00457 
00458 
00459 short **
00460 transpose(R, n)
00461 short **R;
00462 int n;
00463 {
00464   register short **new_R;
00465   register short **temp_R;
00466   register short *nedges;
00467   register short *sp;
00468   register int i;
00469   register int k;
00470 
00471   nedges = NEW2(n, short);
00472 
00473   for (i = 0; i < n; i++)
00474     {
00475       sp = R[i];
00476       if (sp)
00477         {
00478           while (*sp >= 0)
00479             nedges[*sp++]++;
00480         }
00481     }
00482 
00483   new_R = NEW2(n, short *);
00484   temp_R = NEW2(n, short *);
00485 
00486   for (i = 0; i < n; i++)
00487     {
00488       k = nedges[i];
00489       if (k > 0)
00490         {
00491           sp = NEW2(k + 1, short);
00492           new_R[i] = sp;
00493           temp_R[i] = sp;
00494           sp[k] = -1;
00495         }
00496     }
00497 
00498   FREE(nedges);
00499 
00500   for (i = 0; i < n; i++)
00501     {
00502       sp = R[i];
00503       if (sp)
00504         {
00505           while (*sp >= 0)
00506             *temp_R[*sp++]++ = i;
00507         }
00508     }
00509 
00510   FREE(temp_R);
00511 
00512   return (new_R);
00513 }
00514 
00515 
00516 
00517 compute_FOLLOWS()
00518 {
00519   digraph(includes);
00520 }
00521 
00522 
00523 compute_lookaheads()
00524 {
00525   register int i, n;
00526   register unsigned *fp1, *fp2, *fp3;
00527   register shorts *sp, *next;
00528   register unsigned *rowp;
00529 
00530   rowp = LA;
00531   n = lookaheads[nstates];
00532   for (i = 0; i < n; i++)
00533     {
00534       fp3 = rowp + tokensetsize;
00535       for (sp = lookback[i]; sp; sp = sp->next)
00536         {
00537           fp1 = rowp;
00538           fp2 = F + tokensetsize * sp->value;
00539           while (fp1 < fp3)
00540             *fp1++ |= *fp2++;
00541         }
00542       rowp = fp3;
00543     }
00544 
00545   for (i = 0; i < n; i++)
00546     for (sp = lookback[i]; sp; sp = next)
00547       {
00548         next = sp->next;
00549         FREE(sp);
00550       }
00551 
00552   FREE(lookback);
00553   FREE(F);
00554 }
00555 
00556 
00557 digraph(relation)
00558 short **relation;
00559 {
00560   register int i;
00561 
00562   infinity = ngotos + 2;
00563   INDEX = NEW2(ngotos + 1, short);
00564   VERTICES = NEW2(ngotos + 1, short);
00565   top = 0;
00566 
00567   R = relation;
00568 
00569   for (i = 0; i < ngotos; i++)
00570     INDEX[i] = 0;
00571 
00572   for (i = 0; i < ngotos; i++)
00573     {
00574       if (INDEX[i] == 0 && R[i])
00575         traverse(i);
00576     }
00577 
00578   FREE(INDEX);
00579   FREE(VERTICES);
00580 }
00581 
00582 
00583 
00584 traverse(i)
00585 register int i;
00586 {
00587   register unsigned *fp1;
00588   register unsigned *fp2;
00589   register unsigned *fp3;
00590   register int j;
00591   register short *rp;
00592 
00593   int height;
00594   unsigned *base;
00595 
00596   VERTICES[++top] = i;
00597   INDEX[i] = height = top;
00598 
00599   base = F + i * tokensetsize;
00600   fp3 = base + tokensetsize;
00601 
00602   rp = R[i];
00603   if (rp)
00604     {
00605       while ((j = *rp++) >= 0)
00606         {
00607           if (INDEX[j] == 0)
00608             traverse(j);
00609 
00610           if (INDEX[i] > INDEX[j])
00611             INDEX[i] = INDEX[j];
00612 
00613           fp1 = base;
00614           fp2 = F + j * tokensetsize;
00615 
00616           while (fp1 < fp3)
00617             *fp1++ |= *fp2++;
00618         }
00619     }
00620 
00621   if (INDEX[i] == height)
00622     {
00623       for (;;)
00624         {
00625           j = VERTICES[top--];
00626           INDEX[j] = infinity;
00627 
00628           if (i == j)
00629             break;
00630 
00631           fp1 = base;
00632           fp2 = F + j * tokensetsize;
00633 
00634           while (fp1 < fp3)
00635             *fp2++ = *fp1++;
00636         }
00637     }
00638 }

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