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
verbose()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
log_unused()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
log_conflicts()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
print_state(state)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
print_conflicts(state)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
print_core(state)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
print_nulls(state)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
print_actions(stateno)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
print_shifts(p)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
print_reductions(p,defred)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
print_gotos(stateno)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