xref: /csrg-svn/usr.bin/yacc/verbose.c (revision 42698)
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