verbose.c revision 240517
1164190Sjkoshy/* $Id: verbose.c,v 1.10 2012/05/26 00:45:17 tom Exp $ */ 2164190Sjkoshy 3164190Sjkoshy#include "defs.h" 4164190Sjkoshy 5164190Sjkoshystatic void log_conflicts(void); 6164190Sjkoshystatic void log_unused(void); 7164190Sjkoshystatic void print_actions(int stateno); 8164190Sjkoshystatic void print_conflicts(int state); 9164190Sjkoshystatic void print_core(int state); 10164190Sjkoshystatic void print_gotos(int stateno); 11164190Sjkoshystatic void print_nulls(int state); 12164190Sjkoshystatic void print_shifts(action *p); 13164190Sjkoshystatic void print_state(int state); 14164190Sjkoshystatic void print_reductions(action *p, int defred2); 15164190Sjkoshy 16164190Sjkoshystatic short *null_rules; 17164190Sjkoshy 18164190Sjkoshyvoid 19164190Sjkoshyverbose(void) 20164190Sjkoshy{ 21164190Sjkoshy int i; 22164190Sjkoshy 23164190Sjkoshy if (!vflag) 24164190Sjkoshy return; 25164190Sjkoshy 26164190Sjkoshy null_rules = TMALLOC(short, nrules); 27164190Sjkoshy NO_SPACE(null_rules); 28164190Sjkoshy 29164190Sjkoshy fprintf(verbose_file, "\f\n"); 30164190Sjkoshy for (i = 0; i < nstates; i++) 31164190Sjkoshy print_state(i); 32164190Sjkoshy FREE(null_rules); 33164190Sjkoshy 34164190Sjkoshy if (nunused) 35210345Skaiw log_unused(); 36210345Skaiw if (SRtotal || RRtotal) 37164190Sjkoshy log_conflicts(); 38164190Sjkoshy 39164190Sjkoshy fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens, 40164190Sjkoshy nvars); 41164190Sjkoshy fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates); 42165535Sjkoshy} 43164190Sjkoshy 44210345Skaiwstatic void 45164190Sjkoshylog_unused(void) 46164190Sjkoshy{ 47165535Sjkoshy int i; 48210345Skaiw short *p; 49165535Sjkoshy 50165535Sjkoshy fprintf(verbose_file, "\n\nRules never reduced:\n"); 51165535Sjkoshy for (i = 3; i < nrules; ++i) 52210345Skaiw { 53164190Sjkoshy if (!rules_used[i]) 54164190Sjkoshy { 55164190Sjkoshy fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]); 56210345Skaiw for (p = ritem + rrhs[i]; *p >= 0; ++p) 57210345Skaiw fprintf(verbose_file, " %s", symbol_name[*p]); 58210345Skaiw fprintf(verbose_file, " (%d)\n", i - 2); 59210345Skaiw } 60210345Skaiw } 61210345Skaiw} 62210345Skaiw 63210345Skaiwstatic void 64210345Skaiwlog_conflicts(void) 65210345Skaiw{ 66210345Skaiw int i; 67210345Skaiw 68164190Sjkoshy fprintf(verbose_file, "\n\n"); 69164190Sjkoshy for (i = 0; i < nstates; i++) 70164190Sjkoshy { 71164190Sjkoshy if (SRconflicts[i] || RRconflicts[i]) 72164190Sjkoshy { 73164190Sjkoshy fprintf(verbose_file, "State %d contains ", i); 74164190Sjkoshy if (SRconflicts[i] > 0) 75164190Sjkoshy fprintf(verbose_file, "%d shift/reduce conflict%s", 76164190Sjkoshy SRconflicts[i], 77164190Sjkoshy PLURAL(SRconflicts[i])); 78164190Sjkoshy if (SRconflicts[i] && RRconflicts[i]) 79164190Sjkoshy fprintf(verbose_file, ", "); 80164190Sjkoshy if (RRconflicts[i] > 0) 81164190Sjkoshy fprintf(verbose_file, "%d reduce/reduce conflict%s", 82 RRconflicts[i], 83 PLURAL(RRconflicts[i])); 84 fprintf(verbose_file, ".\n"); 85 } 86 } 87} 88 89static void 90print_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 102static void 103print_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 151static void 152print_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 187static void 188print_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 230static void 231print_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 256static void 257print_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 280static void 281print_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 316static void 317print_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