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