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