1 /* $Id: verbose.c,v 1.10 2012/05/26 00:45:17 tom Exp $ */ 2 3 #include "defs.h" 4 5 static void log_conflicts(void); 6 static void log_unused(void); 7 static void print_actions(int stateno); 8 static void print_conflicts(int state); 9 static void print_core(int state); 10 static void print_gotos(int stateno); 11 static void print_nulls(int state); 12 static void print_shifts(action *p); 13 static void print_state(int state); 14 static void print_reductions(action *p, int defred2); 15 16 static short *null_rules; 17 18 void 19 verbose(void) 20 { 21 int i; 22 23 if (!vflag) 24 return; 25 26 null_rules = TMALLOC(short, nrules); 27 NO_SPACE(null_rules); 28 29 fprintf(verbose_file, "\f\n"); 30 for (i = 0; i < nstates; i++) 31 print_state(i); 32 FREE(null_rules); 33 34 if (nunused) 35 log_unused(); 36 if (SRtotal || RRtotal) 37 log_conflicts(); 38 39 fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens, 40 nvars); 41 fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates); 42 } 43 44 static void 45 log_unused(void) 46 { 47 int i; 48 short *p; 49 50 fprintf(verbose_file, "\n\nRules never reduced:\n"); 51 for (i = 3; i < nrules; ++i) 52 { 53 if (!rules_used[i]) 54 { 55 fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]); 56 for (p = ritem + rrhs[i]; *p >= 0; ++p) 57 fprintf(verbose_file, " %s", symbol_name[*p]); 58 fprintf(verbose_file, " (%d)\n", i - 2); 59 } 60 } 61 } 62 63 static void 64 log_conflicts(void) 65 { 66 int i; 67 68 fprintf(verbose_file, "\n\n"); 69 for (i = 0; i < nstates; i++) 70 { 71 if (SRconflicts[i] || RRconflicts[i]) 72 { 73 fprintf(verbose_file, "State %d contains ", i); 74 if (SRconflicts[i] > 0) 75 fprintf(verbose_file, "%d shift/reduce conflict%s", 76 SRconflicts[i], 77 PLURAL(SRconflicts[i])); 78 if (SRconflicts[i] && RRconflicts[i]) 79 fprintf(verbose_file, ", "); 80 if (RRconflicts[i] > 0) 81 fprintf(verbose_file, "%d reduce/reduce conflict%s", 82 RRconflicts[i], 83 PLURAL(RRconflicts[i])); 84 fprintf(verbose_file, ".\n"); 85 } 86 } 87 } 88 89 static void 90 print_state(int state) 91 { 92 if (state) 93 fprintf(verbose_file, "\n\n"); 94 if (SRconflicts[state] || RRconflicts[state]) 95 print_conflicts(state); 96 fprintf(verbose_file, "state %d\n", state); 97 print_core(state); 98 print_nulls(state); 99 print_actions(state); 100 } 101 102 static void 103 print_conflicts(int state) 104 { 105 int symbol, act, number; 106 action *p; 107 108 act = 0; /* not shift/reduce... */ 109 number = -1; 110 symbol = -1; 111 for (p = parser[state]; p; p = p->next) 112 { 113 if (p->suppressed == 2) 114 continue; 115 116 if (p->symbol != symbol) 117 { 118 symbol = p->symbol; 119 number = p->number; 120 if (p->action_code == SHIFT) 121 act = SHIFT; 122 else 123 act = REDUCE; 124 } 125 else if (p->suppressed == 1) 126 { 127 if (state == final_state && symbol == 0) 128 { 129 fprintf(verbose_file, "%d: shift/reduce conflict \ 130 (accept, reduce %d) on $end\n", state, p->number - 2); 131 } 132 else 133 { 134 if (act == SHIFT) 135 { 136 fprintf(verbose_file, "%d: shift/reduce conflict \ 137 (shift %d, reduce %d) on %s\n", state, number, p->number - 2, 138 symbol_name[symbol]); 139 } 140 else 141 { 142 fprintf(verbose_file, "%d: reduce/reduce conflict \ 143 (reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2, 144 symbol_name[symbol]); 145 } 146 } 147 } 148 } 149 } 150 151 static void 152 print_core(int state) 153 { 154 int i; 155 int k; 156 int rule; 157 core *statep; 158 short *sp; 159 short *sp1; 160 161 statep = state_table[state]; 162 k = statep->nitems; 163 164 for (i = 0; i < k; i++) 165 { 166 sp1 = sp = ritem + statep->items[i]; 167 168 while (*sp >= 0) 169 ++sp; 170 rule = -(*sp); 171 fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]); 172 173 for (sp = ritem + rrhs[rule]; sp < sp1; sp++) 174 fprintf(verbose_file, "%s ", symbol_name[*sp]); 175 176 putc('.', verbose_file); 177 178 while (*sp >= 0) 179 { 180 fprintf(verbose_file, " %s", symbol_name[*sp]); 181 sp++; 182 } 183 fprintf(verbose_file, " (%d)\n", -2 - *sp); 184 } 185 } 186 187 static void 188 print_nulls(int state) 189 { 190 action *p; 191 Value_t i, j, k, nnulls; 192 193 nnulls = 0; 194 for (p = parser[state]; p; p = p->next) 195 { 196 if (p->action_code == REDUCE && 197 (p->suppressed == 0 || p->suppressed == 1)) 198 { 199 i = p->number; 200 if (rrhs[i] + 1 == rrhs[i + 1]) 201 { 202 for (j = 0; j < nnulls && i > null_rules[j]; ++j) 203 continue; 204 205 if (j == nnulls) 206 { 207 ++nnulls; 208 null_rules[j] = i; 209 } 210 else if (i != null_rules[j]) 211 { 212 ++nnulls; 213 for (k = (Value_t) (nnulls - 1); k > j; --k) 214 null_rules[k] = null_rules[k - 1]; 215 null_rules[j] = i; 216 } 217 } 218 } 219 } 220 221 for (i = 0; i < nnulls; ++i) 222 { 223 j = null_rules[i]; 224 fprintf(verbose_file, "\t%s : . (%d)\n", symbol_name[rlhs[j]], 225 j - 2); 226 } 227 fprintf(verbose_file, "\n"); 228 } 229 230 static void 231 print_actions(int stateno) 232 { 233 action *p; 234 shifts *sp; 235 int as; 236 237 if (stateno == final_state) 238 fprintf(verbose_file, "\t$end accept\n"); 239 240 p = parser[stateno]; 241 if (p) 242 { 243 print_shifts(p); 244 print_reductions(p, defred[stateno]); 245 } 246 247 sp = shift_table[stateno]; 248 if (sp && sp->nshifts > 0) 249 { 250 as = accessing_symbol[sp->shift[sp->nshifts - 1]]; 251 if (ISVAR(as)) 252 print_gotos(stateno); 253 } 254 } 255 256 static void 257 print_shifts(action *p) 258 { 259 int count; 260 action *q; 261 262 count = 0; 263 for (q = p; q; q = q->next) 264 { 265 if (q->suppressed < 2 && q->action_code == SHIFT) 266 ++count; 267 } 268 269 if (count > 0) 270 { 271 for (; p; p = p->next) 272 { 273 if (p->action_code == SHIFT && p->suppressed == 0) 274 fprintf(verbose_file, "\t%s shift %d\n", 275 symbol_name[p->symbol], p->number); 276 } 277 } 278 } 279 280 static void 281 print_reductions(action *p, int defred2) 282 { 283 int k, anyreds; 284 action *q; 285 286 anyreds = 0; 287 for (q = p; q; q = q->next) 288 { 289 if (q->action_code == REDUCE && q->suppressed < 2) 290 { 291 anyreds = 1; 292 break; 293 } 294 } 295 296 if (anyreds == 0) 297 fprintf(verbose_file, "\t. error\n"); 298 else 299 { 300 for (; p; p = p->next) 301 { 302 if (p->action_code == REDUCE && p->number != defred2) 303 { 304 k = p->number - 2; 305 if (p->suppressed == 0) 306 fprintf(verbose_file, "\t%s reduce %d\n", 307 symbol_name[p->symbol], k); 308 } 309 } 310 311 if (defred2 > 0) 312 fprintf(verbose_file, "\t. reduce %d\n", defred2 - 2); 313 } 314 } 315 316 static void 317 print_gotos(int stateno) 318 { 319 int i, k; 320 int as; 321 short *to_state2; 322 shifts *sp; 323 324 putc('\n', verbose_file); 325 sp = shift_table[stateno]; 326 to_state2 = sp->shift; 327 for (i = 0; i < sp->nshifts; ++i) 328 { 329 k = to_state2[i]; 330 as = accessing_symbol[k]; 331 if (ISVAR(as)) 332 fprintf(verbose_file, "\t%s goto %d\n", symbol_name[as], k); 333 } 334 } 335