verbose.c revision 234949
1234949Sbapt/* $Id: verbose.c,v 1.9 2010/06/09 08:58:29 tom Exp $ */
2234949Sbapt
3234949Sbapt#include "defs.h"
4234949Sbapt
5234949Sbaptstatic void log_conflicts(void);
6234949Sbaptstatic void log_unused(void);
7234949Sbaptstatic void print_actions(int stateno);
8234949Sbaptstatic void print_conflicts(int state);
9234949Sbaptstatic void print_core(int state);
10234949Sbaptstatic void print_gotos(int stateno);
11234949Sbaptstatic void print_nulls(int state);
12234949Sbaptstatic void print_shifts(action *p);
13234949Sbaptstatic void print_state(int state);
14234949Sbaptstatic void print_reductions(action *p, int defred2);
15234949Sbapt
16234949Sbaptstatic short *null_rules;
17234949Sbapt
18234949Sbaptvoid
19234949Sbaptverbose(void)
20234949Sbapt{
21234949Sbapt    int i;
22234949Sbapt
23234949Sbapt    if (!vflag)
24234949Sbapt	return;
25234949Sbapt
26234949Sbapt    null_rules = (short *)MALLOC((unsigned)nrules * sizeof(short));
27234949Sbapt    NO_SPACE(null_rules);
28234949Sbapt
29234949Sbapt    fprintf(verbose_file, "\f\n");
30234949Sbapt    for (i = 0; i < nstates; i++)
31234949Sbapt	print_state(i);
32234949Sbapt    FREE(null_rules);
33234949Sbapt
34234949Sbapt    if (nunused)
35234949Sbapt	log_unused();
36234949Sbapt    if (SRtotal || RRtotal)
37234949Sbapt	log_conflicts();
38234949Sbapt
39234949Sbapt    fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
40234949Sbapt	    nvars);
41234949Sbapt    fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
42234949Sbapt}
43234949Sbapt
44234949Sbaptstatic void
45234949Sbaptlog_unused(void)
46234949Sbapt{
47234949Sbapt    int i;
48234949Sbapt    short *p;
49234949Sbapt
50234949Sbapt    fprintf(verbose_file, "\n\nRules never reduced:\n");
51234949Sbapt    for (i = 3; i < nrules; ++i)
52234949Sbapt    {
53234949Sbapt	if (!rules_used[i])
54234949Sbapt	{
55234949Sbapt	    fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
56234949Sbapt	    for (p = ritem + rrhs[i]; *p >= 0; ++p)
57234949Sbapt		fprintf(verbose_file, " %s", symbol_name[*p]);
58234949Sbapt	    fprintf(verbose_file, "  (%d)\n", i - 2);
59234949Sbapt	}
60234949Sbapt    }
61234949Sbapt}
62234949Sbapt
63234949Sbaptstatic void
64234949Sbaptlog_conflicts(void)
65234949Sbapt{
66234949Sbapt    int i;
67234949Sbapt
68234949Sbapt    fprintf(verbose_file, "\n\n");
69234949Sbapt    for (i = 0; i < nstates; i++)
70234949Sbapt    {
71234949Sbapt	if (SRconflicts[i] || RRconflicts[i])
72234949Sbapt	{
73234949Sbapt	    fprintf(verbose_file, "State %d contains ", i);
74234949Sbapt	    if (SRconflicts[i] > 0)
75234949Sbapt		fprintf(verbose_file, "%d shift/reduce conflict%s",
76234949Sbapt			SRconflicts[i],
77234949Sbapt			PLURAL(SRconflicts[i]));
78234949Sbapt	    if (SRconflicts[i] && RRconflicts[i])
79234949Sbapt		fprintf(verbose_file, ", ");
80234949Sbapt	    if (RRconflicts[i] > 0)
81234949Sbapt		fprintf(verbose_file, "%d reduce/reduce conflict%s",
82234949Sbapt			RRconflicts[i],
83234949Sbapt			PLURAL(RRconflicts[i]));
84234949Sbapt	    fprintf(verbose_file, ".\n");
85234949Sbapt	}
86234949Sbapt    }
87234949Sbapt}
88234949Sbapt
89234949Sbaptstatic void
90234949Sbaptprint_state(int state)
91234949Sbapt{
92234949Sbapt    if (state)
93234949Sbapt	fprintf(verbose_file, "\n\n");
94234949Sbapt    if (SRconflicts[state] || RRconflicts[state])
95234949Sbapt	print_conflicts(state);
96234949Sbapt    fprintf(verbose_file, "state %d\n", state);
97234949Sbapt    print_core(state);
98234949Sbapt    print_nulls(state);
99234949Sbapt    print_actions(state);
100234949Sbapt}
101234949Sbapt
102234949Sbaptstatic void
103234949Sbaptprint_conflicts(int state)
104234949Sbapt{
105234949Sbapt    int symbol, act, number;
106234949Sbapt    action *p;
107234949Sbapt
108234949Sbapt    act = 0;			/* not shift/reduce... */
109234949Sbapt    number = -1;
110234949Sbapt    symbol = -1;
111234949Sbapt    for (p = parser[state]; p; p = p->next)
112234949Sbapt    {
113234949Sbapt	if (p->suppressed == 2)
114234949Sbapt	    continue;
115234949Sbapt
116234949Sbapt	if (p->symbol != symbol)
117234949Sbapt	{
118234949Sbapt	    symbol = p->symbol;
119234949Sbapt	    number = p->number;
120234949Sbapt	    if (p->action_code == SHIFT)
121234949Sbapt		act = SHIFT;
122234949Sbapt	    else
123234949Sbapt		act = REDUCE;
124234949Sbapt	}
125234949Sbapt	else if (p->suppressed == 1)
126234949Sbapt	{
127234949Sbapt	    if (state == final_state && symbol == 0)
128234949Sbapt	    {
129234949Sbapt		fprintf(verbose_file, "%d: shift/reduce conflict \
130234949Sbapt(accept, reduce %d) on $end\n", state, p->number - 2);
131234949Sbapt	    }
132234949Sbapt	    else
133234949Sbapt	    {
134234949Sbapt		if (act == SHIFT)
135234949Sbapt		{
136234949Sbapt		    fprintf(verbose_file, "%d: shift/reduce conflict \
137234949Sbapt(shift %d, reduce %d) on %s\n", state, number, p->number - 2,
138234949Sbapt			    symbol_name[symbol]);
139234949Sbapt		}
140234949Sbapt		else
141234949Sbapt		{
142234949Sbapt		    fprintf(verbose_file, "%d: reduce/reduce conflict \
143234949Sbapt(reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
144234949Sbapt			    symbol_name[symbol]);
145234949Sbapt		}
146234949Sbapt	    }
147234949Sbapt	}
148234949Sbapt    }
149234949Sbapt}
150234949Sbapt
151234949Sbaptstatic void
152234949Sbaptprint_core(int state)
153234949Sbapt{
154234949Sbapt    int i;
155234949Sbapt    int k;
156234949Sbapt    int rule;
157234949Sbapt    core *statep;
158234949Sbapt    short *sp;
159234949Sbapt    short *sp1;
160234949Sbapt
161234949Sbapt    statep = state_table[state];
162234949Sbapt    k = statep->nitems;
163234949Sbapt
164234949Sbapt    for (i = 0; i < k; i++)
165234949Sbapt    {
166234949Sbapt	sp1 = sp = ritem + statep->items[i];
167234949Sbapt
168234949Sbapt	while (*sp >= 0)
169234949Sbapt	    ++sp;
170234949Sbapt	rule = -(*sp);
171234949Sbapt	fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
172234949Sbapt
173234949Sbapt	for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
174234949Sbapt	    fprintf(verbose_file, "%s ", symbol_name[*sp]);
175234949Sbapt
176234949Sbapt	putc('.', verbose_file);
177234949Sbapt
178234949Sbapt	while (*sp >= 0)
179234949Sbapt	{
180234949Sbapt	    fprintf(verbose_file, " %s", symbol_name[*sp]);
181234949Sbapt	    sp++;
182234949Sbapt	}
183234949Sbapt	fprintf(verbose_file, "  (%d)\n", -2 - *sp);
184234949Sbapt    }
185234949Sbapt}
186234949Sbapt
187234949Sbaptstatic void
188234949Sbaptprint_nulls(int state)
189234949Sbapt{
190234949Sbapt    action *p;
191234949Sbapt    Value_t i, j, k, nnulls;
192234949Sbapt
193234949Sbapt    nnulls = 0;
194234949Sbapt    for (p = parser[state]; p; p = p->next)
195234949Sbapt    {
196234949Sbapt	if (p->action_code == REDUCE &&
197234949Sbapt	    (p->suppressed == 0 || p->suppressed == 1))
198234949Sbapt	{
199234949Sbapt	    i = p->number;
200234949Sbapt	    if (rrhs[i] + 1 == rrhs[i + 1])
201234949Sbapt	    {
202234949Sbapt		for (j = 0; j < nnulls && i > null_rules[j]; ++j)
203234949Sbapt		    continue;
204234949Sbapt
205234949Sbapt		if (j == nnulls)
206234949Sbapt		{
207234949Sbapt		    ++nnulls;
208234949Sbapt		    null_rules[j] = i;
209234949Sbapt		}
210234949Sbapt		else if (i != null_rules[j])
211234949Sbapt		{
212234949Sbapt		    ++nnulls;
213234949Sbapt		    for (k = (Value_t) (nnulls - 1); k > j; --k)
214234949Sbapt			null_rules[k] = null_rules[k - 1];
215234949Sbapt		    null_rules[j] = i;
216234949Sbapt		}
217234949Sbapt	    }
218234949Sbapt	}
219234949Sbapt    }
220234949Sbapt
221234949Sbapt    for (i = 0; i < nnulls; ++i)
222234949Sbapt    {
223234949Sbapt	j = null_rules[i];
224234949Sbapt	fprintf(verbose_file, "\t%s : .  (%d)\n", symbol_name[rlhs[j]],
225234949Sbapt		j - 2);
226234949Sbapt    }
227234949Sbapt    fprintf(verbose_file, "\n");
228234949Sbapt}
229234949Sbapt
230234949Sbaptstatic void
231234949Sbaptprint_actions(int stateno)
232234949Sbapt{
233234949Sbapt    action *p;
234234949Sbapt    shifts *sp;
235234949Sbapt    int as;
236234949Sbapt
237234949Sbapt    if (stateno == final_state)
238234949Sbapt	fprintf(verbose_file, "\t$end  accept\n");
239234949Sbapt
240234949Sbapt    p = parser[stateno];
241234949Sbapt    if (p)
242234949Sbapt    {
243234949Sbapt	print_shifts(p);
244234949Sbapt	print_reductions(p, defred[stateno]);
245234949Sbapt    }
246234949Sbapt
247234949Sbapt    sp = shift_table[stateno];
248234949Sbapt    if (sp && sp->nshifts > 0)
249234949Sbapt    {
250234949Sbapt	as = accessing_symbol[sp->shift[sp->nshifts - 1]];
251234949Sbapt	if (ISVAR(as))
252234949Sbapt	    print_gotos(stateno);
253234949Sbapt    }
254234949Sbapt}
255234949Sbapt
256234949Sbaptstatic void
257234949Sbaptprint_shifts(action *p)
258234949Sbapt{
259234949Sbapt    int count;
260234949Sbapt    action *q;
261234949Sbapt
262234949Sbapt    count = 0;
263234949Sbapt    for (q = p; q; q = q->next)
264234949Sbapt    {
265234949Sbapt	if (q->suppressed < 2 && q->action_code == SHIFT)
266234949Sbapt	    ++count;
267234949Sbapt    }
268234949Sbapt
269234949Sbapt    if (count > 0)
270234949Sbapt    {
271234949Sbapt	for (; p; p = p->next)
272234949Sbapt	{
273234949Sbapt	    if (p->action_code == SHIFT && p->suppressed == 0)
274234949Sbapt		fprintf(verbose_file, "\t%s  shift %d\n",
275234949Sbapt			symbol_name[p->symbol], p->number);
276234949Sbapt	}
277234949Sbapt    }
278234949Sbapt}
279234949Sbapt
280234949Sbaptstatic void
281234949Sbaptprint_reductions(action *p, int defred2)
282234949Sbapt{
283234949Sbapt    int k, anyreds;
284234949Sbapt    action *q;
285234949Sbapt
286234949Sbapt    anyreds = 0;
287234949Sbapt    for (q = p; q; q = q->next)
288234949Sbapt    {
289234949Sbapt	if (q->action_code == REDUCE && q->suppressed < 2)
290234949Sbapt	{
291234949Sbapt	    anyreds = 1;
292234949Sbapt	    break;
293234949Sbapt	}
294234949Sbapt    }
295234949Sbapt
296234949Sbapt    if (anyreds == 0)
297234949Sbapt	fprintf(verbose_file, "\t.  error\n");
298234949Sbapt    else
299234949Sbapt    {
300234949Sbapt	for (; p; p = p->next)
301234949Sbapt	{
302234949Sbapt	    if (p->action_code == REDUCE && p->number != defred2)
303234949Sbapt	    {
304234949Sbapt		k = p->number - 2;
305234949Sbapt		if (p->suppressed == 0)
306234949Sbapt		    fprintf(verbose_file, "\t%s  reduce %d\n",
307234949Sbapt			    symbol_name[p->symbol], k);
308234949Sbapt	    }
309234949Sbapt	}
310234949Sbapt
311234949Sbapt	if (defred2 > 0)
312234949Sbapt	    fprintf(verbose_file, "\t.  reduce %d\n", defred2 - 2);
313234949Sbapt    }
314234949Sbapt}
315234949Sbapt
316234949Sbaptstatic void
317234949Sbaptprint_gotos(int stateno)
318234949Sbapt{
319234949Sbapt    int i, k;
320234949Sbapt    int as;
321234949Sbapt    short *to_state2;
322234949Sbapt    shifts *sp;
323234949Sbapt
324234949Sbapt    putc('\n', verbose_file);
325234949Sbapt    sp = shift_table[stateno];
326234949Sbapt    to_state2 = sp->shift;
327234949Sbapt    for (i = 0; i < sp->nshifts; ++i)
328234949Sbapt    {
329234949Sbapt	k = to_state2[i];
330234949Sbapt	as = accessing_symbol[k];
331234949Sbapt	if (ISVAR(as))
332234949Sbapt	    fprintf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
333234949Sbapt    }
334234949Sbapt}
335