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