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