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.3 (Berkeley) 01/20/91"; 13 #endif /* not lint */ 14 15 #include "defs.h" 16 17 static short *null_rules; 18 19 verbose() 20 { 21 register int i; 22 23 if (!vflag) return; 24 25 null_rules = (short *) MALLOC(nrules*sizeof(short)); 26 if (null_rules == 0) no_space(); 27 fprintf(verbose_file, "\f\n"); 28 for (i = 0; i < nstates; i++) 29 print_state(i); 30 FREE(null_rules); 31 32 if (nunused) 33 log_unused(); 34 if (SRtotal || RRtotal) 35 log_conflicts(); 36 37 fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens, 38 nvars); 39 fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates); 40 } 41 42 43 log_unused() 44 { 45 register int i; 46 register short *p; 47 48 fprintf(verbose_file, "\n\nRules never reduced:\n"); 49 for (i = 3; i < nrules; ++i) 50 { 51 if (!rules_used[i]) 52 { 53 fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]); 54 for (p = ritem + rrhs[i]; *p >= 0; ++p) 55 fprintf(verbose_file, " %s", symbol_name[*p]); 56 fprintf(verbose_file, " (%d)\n", i - 2); 57 } 58 } 59 } 60 61 62 log_conflicts() 63 { 64 register int i; 65 66 fprintf(verbose_file, "\n\n"); 67 for (i = 0; i < nstates; i++) 68 { 69 if (SRconflicts[i] || RRconflicts[i]) 70 { 71 fprintf(verbose_file, "State %d contains ", i); 72 if (SRconflicts[i] == 1) 73 fprintf(verbose_file, "1 shift/reduce conflict"); 74 else if (SRconflicts[i] > 1) 75 fprintf(verbose_file, "%d shift/reduce conflicts", 76 SRconflicts[i]); 77 if (SRconflicts[i] && RRconflicts[i]) 78 fprintf(verbose_file, ", "); 79 if (RRconflicts[i] == 1) 80 fprintf(verbose_file, "1 reduce/reduce conflict"); 81 else if (RRconflicts[i] > 1) 82 fprintf(verbose_file, "%d reduce/reduce conflicts", 83 RRconflicts[i]); 84 fprintf(verbose_file, ".\n"); 85 } 86 } 87 } 88 89 90 print_state(state) 91 int state; 92 { 93 if (state) 94 fprintf(verbose_file, "\n\n"); 95 if (SRconflicts[state] || RRconflicts[state]) 96 print_conflicts(state); 97 fprintf(verbose_file, "state %d\n", state); 98 print_core(state); 99 print_nulls(state); 100 print_actions(state); 101 } 102 103 104 print_conflicts(state) 105 int state; 106 { 107 register int symbol, act, number; 108 register action *p; 109 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 152 print_core(state) 153 int state; 154 { 155 register int i; 156 register int k; 157 register int rule; 158 register core *statep; 159 register short *sp; 160 register short *sp1; 161 162 statep = state_table[state]; 163 k = statep->nitems; 164 165 for (i = 0; i < k; i++) 166 { 167 sp1 = sp = ritem + statep->items[i]; 168 169 while (*sp >= 0) ++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 188 print_nulls(state) 189 int state; 190 { 191 register action *p; 192 register int i, j, k, nnulls; 193 194 nnulls = 0; 195 for (p = parser[state]; p; p = p->next) 196 { 197 if (p->action_code == REDUCE && 198 (p->suppressed == 0 || p->suppressed == 1)) 199 { 200 i = p->number; 201 if (rrhs[i] + 1 == rrhs[i+1]) 202 { 203 for (j = 0; j < nnulls && i > null_rules[j]; ++j) 204 continue; 205 206 if (j == nnulls) 207 { 208 ++nnulls; 209 null_rules[j] = i; 210 } 211 else if (i != null_rules[j]) 212 { 213 ++nnulls; 214 for (k = nnulls - 1; k > j; --k) 215 null_rules[k] = null_rules[k-1]; 216 null_rules[j] = i; 217 } 218 } 219 } 220 } 221 222 for (i = 0; i < nnulls; ++i) 223 { 224 j = null_rules[i]; 225 fprintf(verbose_file, "\t%s : . (%d)\n", symbol_name[rlhs[j]], 226 j - 2); 227 } 228 fprintf(verbose_file, "\n"); 229 } 230 231 232 print_actions(stateno) 233 int stateno; 234 { 235 register action *p; 236 register shifts *sp; 237 register int as; 238 239 if (stateno == final_state) 240 fprintf(verbose_file, "\t$end accept\n"); 241 242 p = parser[stateno]; 243 if (p) 244 { 245 print_shifts(p); 246 print_reductions(p, defred[stateno]); 247 } 248 249 sp = shift_table[stateno]; 250 if (sp && sp->nshifts > 0) 251 { 252 as = accessing_symbol[sp->shift[sp->nshifts - 1]]; 253 if (ISVAR(as)) 254 print_gotos(stateno); 255 } 256 } 257 258 259 print_shifts(p) 260 register action *p; 261 { 262 register int count; 263 register action *q; 264 265 count = 0; 266 for (q = p; q; q = q->next) 267 { 268 if (q->suppressed < 2 && q->action_code == SHIFT) 269 ++count; 270 } 271 272 if (count > 0) 273 { 274 for (; p; p = p->next) 275 { 276 if (p->action_code == SHIFT && p->suppressed == 0) 277 fprintf(verbose_file, "\t%s shift %d\n", 278 symbol_name[p->symbol], p->number); 279 } 280 } 281 } 282 283 284 print_reductions(p, defred) 285 register action *p; 286 register int defred; 287 { 288 register int k, anyreds; 289 register action *q; 290 291 anyreds = 0; 292 for (q = p; q ; q = q->next) 293 { 294 if (q->action_code == REDUCE && q->suppressed < 2) 295 { 296 anyreds = 1; 297 break; 298 } 299 } 300 301 if (anyreds == 0) 302 fprintf(verbose_file, "\t. error\n"); 303 else 304 { 305 for (; p; p = p->next) 306 { 307 if (p->action_code == REDUCE && p->number != defred) 308 { 309 k = p->number - 2; 310 if (p->suppressed == 0) 311 fprintf(verbose_file, "\t%s reduce %d\n", 312 symbol_name[p->symbol], k); 313 } 314 } 315 316 if (defred > 0) 317 fprintf(verbose_file, "\t. reduce %d\n", defred - 2); 318 } 319 } 320 321 322 print_gotos(stateno) 323 int stateno; 324 { 325 register int i, k; 326 register int as; 327 register short *to_state; 328 register shifts *sp; 329 330 putc('\n', verbose_file); 331 sp = shift_table[stateno]; 332 to_state = sp->shift; 333 for (i = 0; i < sp->nshifts; ++i) 334 { 335 k = to_state[i]; 336 as = accessing_symbol[k]; 337 if (ISVAR(as)) 338 fprintf(verbose_file, "\t%s goto %d\n", symbol_name[as], k); 339 } 340 } 341