verbose.c revision 235723
1135446Strhodes/* $Id: verbose.c,v 1.9 2010/06/09 08:58:29 tom Exp $ */
2254402Serwin
3135446Strhodes#include "defs.h"
4135446Strhodes
5174187Sdougbstatic void log_conflicts(void);
6135446Strhodesstatic void log_unused(void);
7135446Strhodesstatic void print_actions(int stateno);
8135446Strhodesstatic void print_conflicts(int state);
9135446Strhodesstatic void print_core(int state);
10135446Strhodesstatic void print_gotos(int stateno);
11135446Strhodesstatic void print_nulls(int state);
12135446Strhodesstatic void print_shifts(action *p);
13135446Strhodesstatic void print_state(int state);
14135446Strhodesstatic void print_reductions(action *p, int defred2);
15135446Strhodes
16135446Strhodesstatic short *null_rules;
17135446Strhodes
18234010Sdougbvoid
19135446Strhodesverbose(void)
20170222Sdougb{
21170222Sdougb    int i;
22135446Strhodes
23135446Strhodes    if (!vflag)
24135446Strhodes	return;
25186462Sdougb
26224092Sdougb    null_rules = (short *)MALLOC((unsigned)nrules * sizeof(short));
27224092Sdougb    NO_SPACE(null_rules);
28224092Sdougb
29224092Sdougb    fprintf(verbose_file, "\f\n");
30135446Strhodes    for (i = 0; i < nstates; i++)
31135446Strhodes	print_state(i);
32135446Strhodes    FREE(null_rules);
33135446Strhodes
34135446Strhodes    if (nunused)
35135446Strhodes	log_unused();
36135446Strhodes    if (SRtotal || RRtotal)
37193149Sdougb	log_conflicts();
38135446Strhodes
39135446Strhodes    fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
40186462Sdougb	    nvars);
41135446Strhodes    fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
42135446Strhodes}
43224092Sdougb
44186462Sdougbstatic void
45224092Sdougblog_unused(void)
46193149Sdougb{
47135446Strhodes    int i;
48135446Strhodes    short *p;
49135446Strhodes
50135446Strhodes    fprintf(verbose_file, "\n\nRules never reduced:\n");
51135446Strhodes    for (i = 3; i < nrules; ++i)
52193149Sdougb    {
53135446Strhodes	if (!rules_used[i])
54135446Strhodes	{
55135446Strhodes	    fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
56135446Strhodes	    for (p = ritem + rrhs[i]; *p >= 0; ++p)
57135446Strhodes		fprintf(verbose_file, " %s", symbol_name[*p]);
58170222Sdougb	    fprintf(verbose_file, "  (%d)\n", i - 2);
59135446Strhodes	}
60135446Strhodes    }
61135446Strhodes}
62135446Strhodes
63170222Sdougbstatic void
64224092Sdougblog_conflicts(void)
65135446Strhodes{
66135446Strhodes    int i;
67135446Strhodes
68224092Sdougb    fprintf(verbose_file, "\n\n");
69170222Sdougb    for (i = 0; i < nstates; i++)
70135446Strhodes    {
71135446Strhodes	if (SRconflicts[i] || RRconflicts[i])
72135446Strhodes	{
73135446Strhodes	    fprintf(verbose_file, "State %d contains ", i);
74135446Strhodes	    if (SRconflicts[i] > 0)
75193149Sdougb		fprintf(verbose_file, "%d shift/reduce conflict%s",
76135446Strhodes			SRconflicts[i],
77135446Strhodes			PLURAL(SRconflicts[i]));
78135446Strhodes	    if (SRconflicts[i] && RRconflicts[i])
79135446Strhodes		fprintf(verbose_file, ", ");
80135446Strhodes	    if (RRconflicts[i] > 0)
81135446Strhodes		fprintf(verbose_file, "%d reduce/reduce conflict%s",
82135446Strhodes			RRconflicts[i],
83135446Strhodes			PLURAL(RRconflicts[i]));
84193149Sdougb	    fprintf(verbose_file, ".\n");
85135446Strhodes	}
86135446Strhodes    }
87135446Strhodes}
88135446Strhodes
89135446Strhodesstatic void
90135446Strhodesprint_state(int state)
91135446Strhodes{
92135446Strhodes    if (state)
93135446Strhodes	fprintf(verbose_file, "\n\n");
94135446Strhodes    if (SRconflicts[state] || RRconflicts[state])
95135446Strhodes	print_conflicts(state);
96135446Strhodes    fprintf(verbose_file, "state %d\n", state);
97135446Strhodes    print_core(state);
98135446Strhodes    print_nulls(state);
99135446Strhodes    print_actions(state);
100135446Strhodes}
101135446Strhodes
102193149Sdougbstatic void
103135446Strhodesprint_conflicts(int state)
104135446Strhodes{
105135446Strhodes    int symbol, act, number;
106153816Sdougb    action *p;
107153816Sdougb
108153816Sdougb    act = 0;			/* not shift/reduce... */
109153816Sdougb    number = -1;
110135446Strhodes    symbol = -1;
111224092Sdougb    for (p = parser[state]; p; p = p->next)
112224092Sdougb    {
113224092Sdougb	if (p->suppressed == 2)
114224092Sdougb	    continue;
115170222Sdougb
116135446Strhodes	if (p->symbol != symbol)
117135446Strhodes	{
118135446Strhodes	    symbol = p->symbol;
119135446Strhodes	    number = p->number;
120193149Sdougb	    if (p->action_code == SHIFT)
121193149Sdougb		act = SHIFT;
122135446Strhodes	    else
123135446Strhodes		act = REDUCE;
124135446Strhodes	}
125193149Sdougb	else if (p->suppressed == 1)
126135446Strhodes	{
127135446Strhodes	    if (state == final_state && symbol == 0)
128135446Strhodes	    {
129135446Strhodes		fprintf(verbose_file, "%d: shift/reduce conflict \
130135446Strhodes(accept, reduce %d) on $end\n", state, p->number - 2);
131135446Strhodes	    }
132135446Strhodes	    else
133135446Strhodes	    {
134135446Strhodes		if (act == SHIFT)
135135446Strhodes		{
136135446Strhodes		    fprintf(verbose_file, "%d: shift/reduce conflict \
137135446Strhodes(shift %d, reduce %d) on %s\n", state, number, p->number - 2,
138193149Sdougb			    symbol_name[symbol]);
139135446Strhodes		}
140135446Strhodes		else
141135446Strhodes		{
142135446Strhodes		    fprintf(verbose_file, "%d: reduce/reduce conflict \
143135446Strhodes(reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
144135446Strhodes			    symbol_name[symbol]);
145135446Strhodes		}
146135446Strhodes	    }
147135446Strhodes	}
148135446Strhodes    }
149135446Strhodes}
150135446Strhodes
151193149Sdougbstatic void
152135446Strhodesprint_core(int state)
153135446Strhodes{
154135446Strhodes    int i;
155135446Strhodes    int k;
156224092Sdougb    int rule;
157224092Sdougb    core *statep;
158224092Sdougb    short *sp;
159224092Sdougb    short *sp1;
160224092Sdougb
161224092Sdougb    statep = state_table[state];
162254402Serwin    k = statep->nitems;
163224092Sdougb
164135446Strhodes    for (i = 0; i < k; i++)
165135446Strhodes    {
166135446Strhodes	sp1 = sp = ritem + statep->items[i];
167135446Strhodes
168135446Strhodes	while (*sp >= 0)
169135446Strhodes	    ++sp;
170135446Strhodes	rule = -(*sp);
171224092Sdougb	fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
172224092Sdougb
173224092Sdougb	for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
174224092Sdougb	    fprintf(verbose_file, "%s ", symbol_name[*sp]);
175224092Sdougb
176224092Sdougb	putc('.', verbose_file);
177224092Sdougb
178224092Sdougb	while (*sp >= 0)
179135446Strhodes	{
180135446Strhodes	    fprintf(verbose_file, " %s", symbol_name[*sp]);
181135446Strhodes	    sp++;
182135446Strhodes	}
183135446Strhodes	fprintf(verbose_file, "  (%d)\n", -2 - *sp);
184135446Strhodes    }
185135446Strhodes}
186135446Strhodes
187135446Strhodesstatic void
188135446Strhodesprint_nulls(int state)
189135446Strhodes{
190135446Strhodes    action *p;
191135446Strhodes    Value_t i, j, k, nnulls;
192135446Strhodes
193135446Strhodes    nnulls = 0;
194135446Strhodes    for (p = parser[state]; p; p = p->next)
195135446Strhodes    {
196135446Strhodes	if (p->action_code == REDUCE &&
197135446Strhodes	    (p->suppressed == 0 || p->suppressed == 1))
198135446Strhodes	{
199135446Strhodes	    i = p->number;
200135446Strhodes	    if (rrhs[i] + 1 == rrhs[i + 1])
201135446Strhodes	    {
202135446Strhodes		for (j = 0; j < nnulls && i > null_rules[j]; ++j)
203135446Strhodes		    continue;
204135446Strhodes
205224092Sdougb		if (j == nnulls)
206224092Sdougb		{
207225361Sdougb		    ++nnulls;
208224092Sdougb		    null_rules[j] = i;
209224092Sdougb		}
210224092Sdougb		else if (i != null_rules[j])
211225361Sdougb		{
212224092Sdougb		    ++nnulls;
213225361Sdougb		    for (k = (Value_t) (nnulls - 1); k > j; --k)
214225361Sdougb			null_rules[k] = null_rules[k - 1];
215225361Sdougb		    null_rules[j] = i;
216224092Sdougb		}
217224092Sdougb	    }
218170222Sdougb	}
219170222Sdougb    }
220170222Sdougb
221170222Sdougb    for (i = 0; i < nnulls; ++i)
222170222Sdougb    {
223170222Sdougb	j = null_rules[i];
224170222Sdougb	fprintf(verbose_file, "\t%s : .  (%d)\n", symbol_name[rlhs[j]],
225170222Sdougb		j - 2);
226170222Sdougb    }
227170222Sdougb    fprintf(verbose_file, "\n");
228170222Sdougb}
229170222Sdougb
230170222Sdougbstatic void
231170222Sdougbprint_actions(int stateno)
232170222Sdougb{
233170222Sdougb    action *p;
234170222Sdougb    shifts *sp;
235170222Sdougb    int as;
236170222Sdougb
237170222Sdougb    if (stateno == final_state)
238170222Sdougb	fprintf(verbose_file, "\t$end  accept\n");
239170222Sdougb
240170222Sdougb    p = parser[stateno];
241170222Sdougb    if (p)
242170222Sdougb    {
243170222Sdougb	print_shifts(p);
244170222Sdougb	print_reductions(p, defred[stateno]);
245254402Serwin    }
246254402Serwin
247254402Serwin    sp = shift_table[stateno];
248254402Serwin    if (sp && sp->nshifts > 0)
249254402Serwin    {
250254402Serwin	as = accessing_symbol[sp->shift[sp->nshifts - 1]];
251254402Serwin	if (ISVAR(as))
252254402Serwin	    print_gotos(stateno);
253254402Serwin    }
254254402Serwin}
255254402Serwin
256254402Serwinstatic void
257254402Serwinprint_shifts(action *p)
258254402Serwin{
259254402Serwin    int count;
260254402Serwin    action *q;
261254402Serwin
262254402Serwin    count = 0;
263254402Serwin    for (q = p; q; q = q->next)
264254402Serwin    {
265254402Serwin	if (q->suppressed < 2 && q->action_code == SHIFT)
266254402Serwin	    ++count;
267254402Serwin    }
268254402Serwin
269254402Serwin    if (count > 0)
270254402Serwin    {
271254402Serwin	for (; p; p = p->next)
272254402Serwin	{
273254402Serwin	    if (p->action_code == SHIFT && p->suppressed == 0)
274254402Serwin		fprintf(verbose_file, "\t%s  shift %d\n",
275254402Serwin			symbol_name[p->symbol], p->number);
276254402Serwin	}
277254402Serwin    }
278254402Serwin}
279254402Serwin
280254402Serwinstatic void
281254402Serwinprint_reductions(action *p, int defred2)
282254402Serwin{
283254402Serwin    int k, anyreds;
284254402Serwin    action *q;
285254402Serwin
286254402Serwin    anyreds = 0;
287254402Serwin    for (q = p; q; q = q->next)
288254402Serwin    {
289254402Serwin	if (q->action_code == REDUCE && q->suppressed < 2)
290254402Serwin	{
291254402Serwin	    anyreds = 1;
292254402Serwin	    break;
293254402Serwin	}
294254402Serwin    }
295254402Serwin
296254402Serwin    if (anyreds == 0)
297254402Serwin	fprintf(verbose_file, "\t.  error\n");
298254402Serwin    else
299254402Serwin    {
300254402Serwin	for (; p; p = p->next)
301254402Serwin	{
302254402Serwin	    if (p->action_code == REDUCE && p->number != defred2)
303254402Serwin	    {
304254402Serwin		k = p->number - 2;
305254402Serwin		if (p->suppressed == 0)
306254402Serwin		    fprintf(verbose_file, "\t%s  reduce %d\n",
307254402Serwin			    symbol_name[p->symbol], k);
308254402Serwin	    }
309254402Serwin	}
310254402Serwin
311218384Sdougb	if (defred2 > 0)
312186462Sdougb	    fprintf(verbose_file, "\t.  reduce %d\n", defred2 - 2);
313170222Sdougb    }
314170222Sdougb}
315170222Sdougb
316218384Sdougbstatic void
317218384Sdougbprint_gotos(int stateno)
318170222Sdougb{
319170222Sdougb    int i, k;
320170222Sdougb    int as;
321170222Sdougb    short *to_state2;
322170222Sdougb    shifts *sp;
323193149Sdougb
324170222Sdougb    putc('\n', verbose_file);
325170222Sdougb    sp = shift_table[stateno];
326170222Sdougb    to_state2 = sp->shift;
327170222Sdougb    for (i = 0; i < sp->nshifts; ++i)
328170222Sdougb    {
329170222Sdougb	k = to_state2[i];
330218384Sdougb	as = accessing_symbol[k];
331218384Sdougb	if (ISVAR(as))
332218384Sdougb	    fprintf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
333170222Sdougb    }
334170222Sdougb}
335170222Sdougb