2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / jay / verbose.c
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  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #ifndef lint
38 static char sccsid[] = "@(#)verbose.c   5.3 (Berkeley) 1/20/91";
39 #endif /* not lint */
40
41 #include "defs.h"
42
43 static short *null_rules;
44
45 verbose()
46 {
47     register int i;
48
49     if (!vflag) return;
50
51     null_rules = (short *) MALLOC(nrules*sizeof(short));
52     if (null_rules == 0) no_space();
53     fprintf(verbose_file, "\f\n");
54     for (i = 0; i < nstates; i++)
55         print_state(i);
56     FREE(null_rules);
57
58     if (nunused)
59         log_unused();
60     if (SRtotal || RRtotal)
61         log_conflicts();
62
63     fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
64             nvars);
65     fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
66 }
67
68
69 log_unused()
70 {
71     register int i;
72     register short *p;
73
74     fprintf(verbose_file, "\n\nRules never reduced:\n");
75     for (i = 3; i < nrules; ++i)
76     {
77         if (!rules_used[i])
78         {
79             fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
80             for (p = ritem + rrhs[i]; *p >= 0; ++p)
81                 fprintf(verbose_file, " %s", symbol_name[*p]);
82             fprintf(verbose_file, "  (%d)\n", i - 2);
83         }
84     }
85 }
86
87
88 log_conflicts()
89 {
90     register int i;
91
92     fprintf(verbose_file, "\n\n");
93     for (i = 0; i < nstates; i++)
94     {
95         if (SRconflicts[i] || RRconflicts[i])
96         {
97             fprintf(verbose_file, "State %d contains ", i);
98             if (SRconflicts[i] == 1)
99                 fprintf(verbose_file, "1 shift/reduce conflict");
100             else if (SRconflicts[i] > 1)
101                 fprintf(verbose_file, "%d shift/reduce conflicts",
102                         SRconflicts[i]);
103             if (SRconflicts[i] && RRconflicts[i])
104                 fprintf(verbose_file, ", ");
105             if (RRconflicts[i] == 1)
106                 fprintf(verbose_file, "1 reduce/reduce conflict");
107             else if (RRconflicts[i] > 1)
108                 fprintf(verbose_file, "%d reduce/reduce conflicts",
109                         RRconflicts[i]);
110             fprintf(verbose_file, ".\n");
111         }
112     }
113 }
114
115
116 print_state(state)
117 int state;
118 {
119     if (state)
120         fprintf(verbose_file, "\n\n");
121     if (SRconflicts[state] || RRconflicts[state])
122         print_conflicts(state);
123     fprintf(verbose_file, "state %d\n", state);
124     print_core(state);
125     print_nulls(state);
126     print_actions(state);
127 }
128
129
130 print_conflicts(state)
131 int state;
132 {
133     register int symbol, act, number;
134     register action *p;
135
136     symbol = -1;
137     for (p = parser[state]; p; p = p->next)
138     {
139         if (p->suppressed == 2)
140             continue;
141
142         if (p->symbol != symbol)
143         {
144             symbol = p->symbol;
145             number = p->number;
146             if (p->action_code == SHIFT)
147                 act = SHIFT;
148             else
149                 act = REDUCE;
150         }
151         else if (p->suppressed == 1)
152         {
153             if (state == final_state && symbol == 0)
154             {
155                 fprintf(verbose_file, "%d: shift/reduce conflict \
156 (accept, reduce %d) on $end\n", state, p->number - 2);
157             }
158             else
159             {
160                 if (act == SHIFT)
161                 {
162                     fprintf(verbose_file, "%d: shift/reduce conflict \
163 (shift %d, reduce %d) on %s\n", state, number, p->number - 2,
164                             symbol_name[symbol]);
165                 }
166                 else
167                 {
168                     fprintf(verbose_file, "%d: reduce/reduce conflict \
169 (reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
170                             symbol_name[symbol]);
171                 }
172             }
173         }
174     }
175 }
176
177
178 print_core(state)
179 int state;
180 {
181     register int i;
182     register int k;
183     register int rule;
184     register core *statep;
185     register short *sp;
186     register short *sp1;
187
188     statep = state_table[state];
189     k = statep->nitems;
190
191     for (i = 0; i < k; i++)
192     {
193         sp1 = sp = ritem + statep->items[i];
194
195         while (*sp >= 0) ++sp;
196         rule = -(*sp);
197         fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
198
199         for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
200             fprintf(verbose_file, "%s ", symbol_name[*sp]);
201
202         putc('.', verbose_file);
203
204         while (*sp >= 0)
205         {
206             fprintf(verbose_file, " %s", symbol_name[*sp]);
207             sp++;
208         }
209         fprintf(verbose_file, "  (%d)\n", -2 - *sp);
210     }
211 }
212
213
214 print_nulls(state)
215 int state;
216 {
217     register action *p;
218     register int i, j, k, nnulls;
219
220     nnulls = 0;
221     for (p = parser[state]; p; p = p->next)
222     {
223         if (p->action_code == REDUCE &&
224                 (p->suppressed == 0 || p->suppressed == 1))
225         {
226             i = p->number;
227             if (rrhs[i] + 1 == rrhs[i+1])
228             {
229                 for (j = 0; j < nnulls && i > null_rules[j]; ++j)
230                     continue;
231
232                 if (j == nnulls)
233                 {
234                     ++nnulls;
235                     null_rules[j] = i;
236                 }
237                 else if (i != null_rules[j])
238                 {
239                     ++nnulls;
240                     for (k = nnulls - 1; k > j; --k)
241                         null_rules[k] = null_rules[k-1];
242                     null_rules[j] = i;
243                 }
244             }
245         }
246     }
247
248     for (i = 0; i < nnulls; ++i)
249     {
250         j = null_rules[i];
251         fprintf(verbose_file, "\t%s : .  (%d)\n", symbol_name[rlhs[j]],
252                 j - 2);
253     }
254     fprintf(verbose_file, "\n");
255 }
256
257
258 print_actions(stateno)
259 int stateno;
260 {
261     register action *p;
262     register shifts *sp;
263     register int as;
264
265     if (stateno == final_state)
266         fprintf(verbose_file, "\t$end  accept\n");
267
268     p = parser[stateno];
269     if (p)
270     {
271         print_shifts(p);
272         print_reductions(p, defred[stateno]);
273     }
274
275     sp = shift_table[stateno];
276     if (sp && sp->nshifts > 0)
277     {
278         as = accessing_symbol[sp->shift[sp->nshifts - 1]];
279         if (ISVAR(as))
280             print_gotos(stateno);
281     }
282 }
283
284
285 print_shifts(p)
286 register action *p;
287 {
288     register int count;
289     register action *q;
290
291     count = 0;
292     for (q = p; q; q = q->next)
293     {
294         if (q->suppressed < 2 && q->action_code == SHIFT)
295             ++count;
296     }
297
298     if (count > 0)
299     {
300         for (; p; p = p->next)
301         {
302             if (p->action_code == SHIFT && p->suppressed == 0)
303                 fprintf(verbose_file, "\t%s  shift %d\n",
304                             symbol_name[p->symbol], p->number);
305         }
306     }
307 }
308
309
310 print_reductions(p, defred)
311 register action *p;
312 register int defred;
313 {
314     register int k, anyreds;
315     register action *q;
316
317     anyreds = 0;
318     for (q = p; q ; q = q->next)
319     {
320         if (q->action_code == REDUCE && q->suppressed < 2)
321         {
322             anyreds = 1;
323             break;
324         }
325     }
326
327     if (anyreds == 0)
328         fprintf(verbose_file, "\t.  error\n");
329     else
330     {
331         for (; p; p = p->next)
332         {
333             if (p->action_code == REDUCE && p->number != defred)
334             {
335                 k = p->number - 2;
336                 if (p->suppressed == 0)
337                     fprintf(verbose_file, "\t%s  reduce %d\n",
338                             symbol_name[p->symbol], k);
339             }
340         }
341
342         if (defred > 0)
343             fprintf(verbose_file, "\t.  reduce %d\n", defred - 2);
344     }
345 }
346
347
348 print_gotos(stateno)
349 int stateno;
350 {
351     register int i, k;
352     register int as;
353     register short *to_state;
354     register shifts *sp;
355
356     putc('\n', verbose_file);
357     sp = shift_table[stateno];
358     to_state = sp->shift;
359     for (i = 0; i < sp->nshifts; ++i)
360     {
361         k = to_state[i];
362         as = accessing_symbol[k];
363         if (ISVAR(as))
364             fprintf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
365     }
366 }