Pristine Ack-5.5
[Ack-5.5.git] / util / byacc / verbose.c
1
2 #include "defs.h"
3
4
5 static short *null_rules;
6
7 verbose()
8 {
9     register int i;
10
11     if (!vflag) return;
12
13     null_rules = (short *) MALLOC(nrules*sizeof(short));
14     if (null_rules == 0) no_space();
15     fprintf(verbose_file, "\f\n");
16     for (i = 0; i < nstates; i++)
17         print_state(i);
18     FREE(null_rules);
19
20     if (nunused)
21         log_unused();
22     if (SRtotal || RRtotal)
23         log_conflicts();
24
25     fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
26             nvars);
27     fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
28 }
29
30
31 log_unused()
32 {
33     register int i;
34     register short *p;
35
36     fprintf(verbose_file, "\n\nRules never reduced:\n");
37     for (i = 3; i < nrules; ++i)
38     {
39         if (!rules_used[i])
40         {
41             fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
42             for (p = ritem + rrhs[i]; *p >= 0; ++p)
43                 fprintf(verbose_file, " %s", symbol_name[*p]);
44             fprintf(verbose_file, "  (%d)\n", i - 2);
45         }
46     }
47 }
48
49
50 log_conflicts()
51 {
52     register int i;
53
54     fprintf(verbose_file, "\n\n");
55     for (i = 0; i < nstates; i++)
56     {
57         if (SRconflicts[i] || RRconflicts[i])
58         {
59             fprintf(verbose_file, "State %d contains ", i);
60             if (SRconflicts[i] == 1)
61                 fprintf(verbose_file, "1 shift/reduce conflict");
62             else if (SRconflicts[i] > 1)
63                 fprintf(verbose_file, "%d shift/reduce conflicts",
64                         SRconflicts[i]);
65             if (SRconflicts[i] && RRconflicts[i])
66                 fprintf(verbose_file, ", ");
67             if (RRconflicts[i] == 1)
68                 fprintf(verbose_file, "1 reduce/reduce conflict");
69             else if (RRconflicts[i] > 1)
70                 fprintf(verbose_file, "%d reduce/reduce conflicts",
71                         RRconflicts[i]);
72             fprintf(verbose_file, ".\n");
73         }
74     }
75 }
76
77
78 print_state(state)
79 int state;
80 {
81     if (state)
82         fprintf(verbose_file, "\n\n");
83     if (SRconflicts[state] || RRconflicts[state])
84         print_conflicts(state);
85     fprintf(verbose_file, "state %d\n", state);
86     print_core(state);
87     print_nulls(state);
88     print_actions(state);
89 }
90
91
92 print_conflicts(state)
93 int state;
94 {
95     register int symbol, act, number;
96     register action *p;
97
98     symbol = -1;
99     for (p = parser[state]; p; p = p->next)
100     {
101         if (p->suppressed == 2)
102             continue;
103
104         if (p->symbol != symbol)
105         {
106             symbol = p->symbol;
107             number = p->number;
108             if (p->action_code == SHIFT)
109                 act = SHIFT;
110             else
111                 act = REDUCE;
112         }
113         else if (p->suppressed == 1)
114         {
115             if (state == final_state && symbol == 0)
116             {
117                 fprintf(verbose_file, "%d: shift/reduce conflict \
118 (accept, reduce %d) on $end\n", state, p->number - 2);
119             }
120             else
121             {
122                 if (act == SHIFT)
123                 {
124                     fprintf(verbose_file, "%d: shift/reduce conflict \
125 (shift %d, reduce %d) on %s\n", state, number, p->number - 2,
126                             symbol_name[symbol]);
127                 }
128                 else
129                 {
130                     fprintf(verbose_file, "%d: reduce/reduce conflict \
131 (reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
132                             symbol_name[symbol]);
133                 }
134             }
135         }
136     }
137 }
138
139
140 print_core(state)
141 int state;
142 {
143     register int i;
144     register int k;
145     register int rule;
146     register core *statep;
147     register short *sp;
148     register short *sp1;
149
150     statep = state_table[state];
151     k = statep->nitems;
152
153     for (i = 0; i < k; i++)
154     {
155         sp1 = sp = ritem + statep->items[i];
156
157         while (*sp >= 0) ++sp;
158         rule = -(*sp);
159         fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
160
161         for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
162             fprintf(verbose_file, "%s ", symbol_name[*sp]);
163
164         putc('.', verbose_file);
165
166         while (*sp >= 0)
167         {
168             fprintf(verbose_file, " %s", symbol_name[*sp]);
169             sp++;
170         }
171         fprintf(verbose_file, "  (%d)\n", -2 - *sp);
172     }
173 }
174
175
176 print_nulls(state)
177 int state;
178 {
179     register action *p;
180     register int i, j, k, nnulls;
181
182     nnulls = 0;
183     for (p = parser[state]; p; p = p->next)
184     {
185         if (p->action_code == REDUCE &&
186                 (p->suppressed == 0 || p->suppressed == 1))
187         {
188             i = p->number;
189             if (rrhs[i] + 1 == rrhs[i+1])
190             {
191                 for (j = 0; j < nnulls && i > null_rules[j]; ++j)
192                     continue;
193
194                 if (j == nnulls)
195                 {
196                     ++nnulls;
197                     null_rules[j] = i;
198                 }
199                 else if (i != null_rules[j])
200                 {
201                     ++nnulls;
202                     for (k = nnulls - 1; k > j; --k)
203                         null_rules[k] = null_rules[k-1];
204                     null_rules[j] = i;
205                 }
206             }
207         }
208     }
209
210     for (i = 0; i < nnulls; ++i)
211     {
212         j = null_rules[i];
213         fprintf(verbose_file, "\t%s : .  (%d)\n", symbol_name[rlhs[j]],
214                 j - 2);
215     }
216     fprintf(verbose_file, "\n");
217 }
218
219
220 print_actions(stateno)
221 int stateno;
222 {
223     register action *p;
224     register shifts *sp;
225     register int as;
226
227     if (stateno == final_state)
228         fprintf(verbose_file, "\t$end  accept\n");
229
230     p = parser[stateno];
231     if (p)
232     {
233         print_shifts(p);
234         print_reductions(p, defred[stateno]);
235     }
236
237     sp = shift_table[stateno];
238     if (sp && sp->nshifts > 0)
239     {
240         as = accessing_symbol[sp->shift[sp->nshifts - 1]];
241         if (ISVAR(as))
242             print_gotos(stateno);
243     }
244 }
245
246
247 print_shifts(p)
248 register action *p;
249 {
250     register int count;
251     register action *q;
252
253     count = 0;
254     for (q = p; q; q = q->next)
255     {
256         if (q->suppressed < 2 && q->action_code == SHIFT)
257             ++count;
258     }
259
260     if (count > 0)
261     {
262         for (; p; p = p->next)
263         {
264             if (p->action_code == SHIFT && p->suppressed == 0)
265                 fprintf(verbose_file, "\t%s  shift %d\n",
266                             symbol_name[p->symbol], p->number);
267         }
268     }
269 }
270
271
272 print_reductions(p, defred)
273 register action *p;
274 register int defred;
275 {
276     register int k, anyreds;
277     register action *q;
278
279     anyreds = 0;
280     for (q = p; q ; q = q->next)
281     {
282         if (q->action_code == REDUCE && q->suppressed < 2)
283         {
284             anyreds = 1;
285             break;
286         }
287     }
288
289     if (anyreds == 0)
290         fprintf(verbose_file, "\t.  error\n");
291     else
292     {
293         for (; p; p = p->next)
294         {
295             if (p->action_code == REDUCE && p->number != defred)
296             {
297                 k = p->number - 2;
298                 if (p->suppressed == 0)
299                     fprintf(verbose_file, "\t%s  reduce %d\n",
300                             symbol_name[p->symbol], k);
301             }
302         }
303
304         if (defred > 0)
305             fprintf(verbose_file, "\t.  reduce %d\n", defred - 2);
306     }
307 }
308
309
310 print_gotos(stateno)
311 int stateno;
312 {
313     register int i, k;
314     register int as;
315     register short *to_state;
316     register shifts *sp;
317
318     putc('\n', verbose_file);
319     sp = shift_table[stateno];
320     to_state = sp->shift;
321     for (i = 0; i < sp->nshifts; ++i)
322     {
323         k = to_state[i];
324         as = accessing_symbol[k];
325         if (ISVAR(as))
326             fprintf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
327     }
328 }
329