mkpar.c

Go to the documentation of this file.
00001 
00002 #include "defs.h"
00003 
00004 action **parser;
00005 int SRtotal;
00006 int RRtotal;
00007 short *SRconflicts;
00008 short *RRconflicts;
00009 short *defred;
00010 short *rules_used;
00011 short nunused;
00012 short final_state;
00013 
00014 static int SRcount;
00015 static int RRcount;
00016 
00017 extern action *parse_actions();
00018 extern action *get_shifts();
00019 extern action *add_reductions();
00020 extern action *add_reduce();
00021 
00022 
00023 make_parser()
00024 {
00025     register int i;
00026 
00027     parser = NEW2(nstates, action *);
00028     for (i = 0; i < nstates; i++)
00029         parser[i] = parse_actions(i);
00030 
00031     find_final_state();
00032     remove_conflicts();
00033     unused_rules();
00034     if (SRtotal + RRtotal > 0) total_conflicts();
00035     defreds();
00036 }
00037 
00038 
00039 action *
00040 parse_actions(stateno)
00041 register int stateno;
00042 {
00043     register action *actions;
00044 
00045     actions = get_shifts(stateno);
00046     actions = add_reductions(stateno, actions);
00047     return (actions);
00048 }
00049 
00050 
00051 action *
00052 get_shifts(stateno)
00053 int stateno;
00054 {
00055     register action *actions, *temp;
00056     register shifts *sp;
00057     register short *to_state;
00058     register int i, k;
00059     register int symbol;
00060 
00061     actions = 0;
00062     sp = shift_table[stateno];
00063     if (sp)
00064     {
00065         to_state = sp->shift;
00066         for (i = sp->nshifts - 1; i >= 0; i--)
00067         {
00068             k = to_state[i];
00069             symbol = accessing_symbol[k];
00070             if (ISTOKEN(symbol))
00071             {
00072                 temp = NEW(action);
00073                 temp->next = actions;
00074                 temp->symbol = symbol;
00075                 temp->number = k;
00076                 temp->prec = symbol_prec[symbol];
00077                 temp->action_code = SHIFT;
00078                 temp->assoc = symbol_assoc[symbol];
00079                 actions = temp;
00080             }
00081         }
00082     }
00083     return (actions);
00084 }
00085 
00086 action *
00087 add_reductions(stateno, actions)
00088 int stateno;
00089 register action *actions;
00090 {
00091     register int i, j, m, n;
00092     register int ruleno, tokensetsize;
00093     register unsigned *rowp;
00094 
00095     tokensetsize = WORDSIZE(ntokens);
00096     m = lookaheads[stateno];
00097     n = lookaheads[stateno + 1];
00098     for (i = m; i < n; i++)
00099     {
00100         ruleno = LAruleno[i];
00101         rowp = LA + i * tokensetsize;
00102         for (j = ntokens - 1; j >= 0; j--)
00103         {
00104             if (BIT(rowp, j))
00105                 actions = add_reduce(actions, ruleno, j);
00106         }
00107     }
00108     return (actions);
00109 }
00110 
00111 
00112 action *
00113 add_reduce(actions, ruleno, symbol)
00114 register action *actions;
00115 register int ruleno, symbol;
00116 {
00117     register action *temp, *prev, *next;
00118 
00119     prev = 0;
00120     for (next = actions; next && next->symbol < symbol; next = next->next)
00121         prev = next;
00122 
00123     while (next && next->symbol == symbol && next->action_code == SHIFT)
00124     {
00125         prev = next;
00126         next = next->next;
00127     }
00128 
00129     while (next && next->symbol == symbol &&
00130             next->action_code == REDUCE && next->number < ruleno)
00131     {
00132         prev = next;
00133         next = next->next;
00134     }
00135 
00136     temp = NEW(action);
00137     temp->next = next;
00138     temp->symbol = symbol;
00139     temp->number = ruleno;
00140     temp->prec = rprec[ruleno];
00141     temp->action_code = REDUCE;
00142     temp->assoc = rassoc[ruleno];
00143 
00144     if (prev)
00145         prev->next = temp;
00146     else
00147         actions = temp;
00148 
00149     return (actions);
00150 }
00151 
00152 
00153 find_final_state()
00154 {
00155     register int goal, i;
00156     register short *to_state;
00157     register shifts *p;
00158 
00159     p = shift_table[0];
00160     to_state = p->shift;
00161     goal = ritem[1];
00162     for (i = p->nshifts - 1; i >= 0; --i)
00163     {
00164         final_state = to_state[i];
00165         if (accessing_symbol[final_state] == goal) break;
00166     }
00167 }
00168 
00169 
00170 unused_rules()
00171 {
00172     register int i;
00173     register action *p;
00174 
00175     rules_used = (short *) MALLOC(nrules*sizeof(short));
00176     if (rules_used == 0) no_space();
00177 
00178     for (i = 0; i < nrules; ++i)
00179         rules_used[i] = 0;
00180 
00181     for (i = 0; i < nstates; ++i)
00182     {
00183         for (p = parser[i]; p; p = p->next)
00184         {
00185             if (p->action_code == REDUCE && p->suppressed == 0)
00186                 rules_used[p->number] = 1;
00187         }
00188     }
00189 
00190     nunused = 0;
00191     for (i = 3; i < nrules; ++i)
00192         if (!rules_used[i]) ++nunused;
00193 
00194     if (nunused)
00195         if (nunused == 1)
00196             fprintf(stderr, "%s: 1 rule never reduced\n", myname);
00197         else
00198             fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
00199 }
00200 
00201 
00202 remove_conflicts()
00203 {
00204     register int i;
00205     register int symbol;
00206     register action *p, *pref;
00207 
00208     SRtotal = 0;
00209     RRtotal = 0;
00210     SRconflicts = NEW2(nstates, short);
00211     RRconflicts = NEW2(nstates, short);
00212     for (i = 0; i < nstates; i++)
00213     {
00214         SRcount = 0;
00215         RRcount = 0;
00216         symbol = -1;
00217         for (p = parser[i]; p; p = p->next)
00218         {
00219             if (p->symbol != symbol)
00220             {
00221                 pref = p;
00222                 symbol = p->symbol;
00223             }
00224             else if (i == final_state && symbol == 0)
00225             {
00226                 SRcount++;
00227                 p->suppressed = 1;
00228             }
00229             else if (pref->action_code == SHIFT)
00230             {
00231                 if (pref->prec > 0 && p->prec > 0)
00232                 {
00233                     if (pref->prec < p->prec)
00234                     {
00235                         pref->suppressed = 2;
00236                         pref = p;
00237                     }
00238                     else if (pref->prec > p->prec)
00239                     {
00240                         p->suppressed = 2;
00241                     }
00242                     else if (pref->assoc == LEFT)
00243                     {
00244                         pref->suppressed = 2;
00245                         pref = p;
00246                     }
00247                     else if (pref->assoc == RIGHT)
00248                     {
00249                         p->suppressed = 2;
00250                     }
00251                     else
00252                     {
00253                         pref->suppressed = 2;
00254                         p->suppressed = 2;
00255                     }
00256                 }
00257                 else
00258                 {
00259                     SRcount++;
00260                     p->suppressed = 1;
00261                 }
00262             }
00263             else
00264             {
00265                 RRcount++;
00266                 p->suppressed = 1;
00267             }
00268         }
00269         SRtotal += SRcount;
00270         RRtotal += RRcount;
00271         SRconflicts[i] = SRcount;
00272         RRconflicts[i] = RRcount;
00273     }
00274 }
00275 
00276 
00277 total_conflicts()
00278 {
00279     fprintf(stderr, "%s: ", myname);
00280     if (SRtotal == 1)
00281         fprintf(stderr, "1 shift/reduce conflict");
00282     else if (SRtotal > 1)
00283         fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
00284 
00285     if (SRtotal && RRtotal)
00286         fprintf(stderr, ", ");
00287 
00288     if (RRtotal == 1)
00289         fprintf(stderr, "1 reduce/reduce conflict");
00290     else if (RRtotal > 1)
00291         fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
00292 
00293     fprintf(stderr, ".\n");
00294 }
00295 
00296 
00297 int
00298 sole_reduction(stateno)
00299 int stateno;
00300 {
00301     register int count, ruleno;
00302     register action *p;
00303 
00304     count = 0;
00305     ruleno = 0; 
00306     for (p = parser[stateno]; p; p = p->next)
00307     {
00308         if (p->action_code == SHIFT && p->suppressed == 0)
00309             return (0);
00310         else if (p->action_code == REDUCE && p->suppressed == 0)
00311         {
00312             if (ruleno > 0 && p->number != ruleno)
00313                 return (0);
00314             if (p->symbol != 1)
00315                 ++count;
00316             ruleno = p->number;
00317         }
00318     }
00319 
00320     if (count == 0)
00321         return (0);
00322     return (ruleno);
00323 }
00324 
00325 
00326 defreds()
00327 {
00328     register int i;
00329 
00330     defred = NEW2(nstates, short);
00331     for (i = 0; i < nstates; i++)
00332         defred[i] = sole_reduction(i);
00333 }
00334  
00335 free_action_row(p)
00336 register action *p;
00337 {
00338   register action *q;
00339 
00340   while (p)
00341     {
00342       q = p->next;
00343       FREE(p);
00344       p = q;
00345     }
00346 }
00347 
00348 free_parser()
00349 {
00350   register int i;
00351 
00352   for (i = 0; i < nstates; i++)
00353     free_action_row(parser[i]);
00354 
00355   FREE(parser);
00356 }
00357 

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