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