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