Annotation of src/usr.bin/yacc/verbose.c, Revision 1.9
1.9 ! pvalchev 1: /* $OpenBSD: verbose.c,v 1.8 2003/06/19 16:34:53 pvalchev 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.9 ! pvalchev 40: static char rcsid[] = "$OpenBSD: verbose.c,v 1.8 2003/06/19 16:34:53 pvalchev 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.8 pvalchev 60: verbose(void)
1.1 deraadt 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.8 pvalchev 85: log_unused(void)
1.1 deraadt 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.8 pvalchev 105: log_conflicts(void)
1.1 deraadt 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.8 pvalchev 134: print_state(int state)
1.1 deraadt 135: {
136: if (state)
137: fprintf(verbose_file, "\n\n");
138: if (SRconflicts[state] || RRconflicts[state])
139: print_conflicts(state);
140: fprintf(verbose_file, "state %d\n", state);
141: print_core(state);
142: print_nulls(state);
143: print_actions(state);
144: }
145:
146:
1.4 pvalchev 147: void
1.8 pvalchev 148: print_conflicts(int state)
1.1 deraadt 149: {
1.9 ! pvalchev 150: int symbol, act = REDUCE, number = 0;
1.5 mpech 151: action *p;
1.1 deraadt 152:
153: symbol = -1;
154: for (p = parser[state]; p; p = p->next)
155: {
156: if (p->suppressed == 2)
157: continue;
158:
159: if (p->symbol != symbol)
160: {
161: symbol = p->symbol;
162: number = p->number;
163: if (p->action_code == SHIFT)
164: act = SHIFT;
165: else
166: act = REDUCE;
167: }
168: else if (p->suppressed == 1)
169: {
170: if (state == final_state && symbol == 0)
171: {
172: fprintf(verbose_file, "%d: shift/reduce conflict \
173: (accept, reduce %d) on $end\n", state, p->number - 2);
174: }
175: else
176: {
177: if (act == SHIFT)
178: {
179: fprintf(verbose_file, "%d: shift/reduce conflict \
180: (shift %d, reduce %d) on %s\n", state, number, p->number - 2,
181: symbol_name[symbol]);
182: }
183: else
184: {
185: fprintf(verbose_file, "%d: reduce/reduce conflict \
186: (reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
187: symbol_name[symbol]);
188: }
189: }
190: }
191: }
192: }
193:
194:
1.4 pvalchev 195: void
1.8 pvalchev 196: print_core(int state)
1.1 deraadt 197: {
1.5 mpech 198: int i;
199: int k;
200: int rule;
201: core *statep;
202: short *sp;
203: short *sp1;
1.1 deraadt 204:
205: statep = state_table[state];
206: k = statep->nitems;
207:
208: for (i = 0; i < k; i++)
209: {
210: sp1 = sp = ritem + statep->items[i];
211:
212: while (*sp >= 0) ++sp;
213: rule = -(*sp);
214: fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
215:
216: for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
217: fprintf(verbose_file, "%s ", symbol_name[*sp]);
218:
219: putc('.', verbose_file);
220:
221: while (*sp >= 0)
222: {
223: fprintf(verbose_file, " %s", symbol_name[*sp]);
224: sp++;
225: }
226: fprintf(verbose_file, " (%d)\n", -2 - *sp);
227: }
228: }
229:
230:
1.4 pvalchev 231: void
1.8 pvalchev 232: print_nulls(int state)
1.1 deraadt 233: {
1.5 mpech 234: action *p;
235: int i, j, k, nnulls;
1.1 deraadt 236:
237: nnulls = 0;
238: for (p = parser[state]; p; p = p->next)
239: {
240: if (p->action_code == REDUCE &&
241: (p->suppressed == 0 || p->suppressed == 1))
242: {
243: i = p->number;
244: if (rrhs[i] + 1 == rrhs[i+1])
245: {
246: for (j = 0; j < nnulls && i > null_rules[j]; ++j)
247: continue;
248:
249: if (j == nnulls)
250: {
251: ++nnulls;
252: null_rules[j] = i;
253: }
254: else if (i != null_rules[j])
255: {
256: ++nnulls;
257: for (k = nnulls - 1; k > j; --k)
258: null_rules[k] = null_rules[k-1];
259: null_rules[j] = i;
260: }
261: }
262: }
263: }
264:
265: for (i = 0; i < nnulls; ++i)
266: {
267: j = null_rules[i];
268: fprintf(verbose_file, "\t%s : . (%d)\n", symbol_name[rlhs[j]],
269: j - 2);
270: }
271: fprintf(verbose_file, "\n");
272: }
273:
274:
1.4 pvalchev 275: void
1.8 pvalchev 276: print_actions(int stateno)
1.1 deraadt 277: {
1.5 mpech 278: action *p;
279: shifts *sp;
280: int as;
1.1 deraadt 281:
282: if (stateno == final_state)
283: fprintf(verbose_file, "\t$end accept\n");
284:
285: p = parser[stateno];
286: if (p)
287: {
288: print_shifts(p);
289: print_reductions(p, defred[stateno]);
290: }
291:
292: sp = shift_table[stateno];
293: if (sp && sp->nshifts > 0)
294: {
295: as = accessing_symbol[sp->shift[sp->nshifts - 1]];
296: if (ISVAR(as))
297: print_gotos(stateno);
298: }
299: }
300:
301:
1.4 pvalchev 302: void
1.8 pvalchev 303: print_shifts(action *p)
1.1 deraadt 304: {
1.5 mpech 305: int count;
306: action *q;
1.1 deraadt 307:
308: count = 0;
309: for (q = p; q; q = q->next)
310: {
311: if (q->suppressed < 2 && q->action_code == SHIFT)
312: ++count;
313: }
314:
315: if (count > 0)
316: {
317: for (; p; p = p->next)
318: {
319: if (p->action_code == SHIFT && p->suppressed == 0)
320: fprintf(verbose_file, "\t%s shift %d\n",
321: symbol_name[p->symbol], p->number);
322: }
323: }
324: }
325:
326:
1.4 pvalchev 327: void
1.8 pvalchev 328: print_reductions(action *p, int defred)
1.1 deraadt 329: {
1.5 mpech 330: int k, anyreds;
331: action *q;
1.1 deraadt 332:
333: anyreds = 0;
334: for (q = p; q ; q = q->next)
335: {
336: if (q->action_code == REDUCE && q->suppressed < 2)
337: {
338: anyreds = 1;
339: break;
340: }
341: }
342:
343: if (anyreds == 0)
344: fprintf(verbose_file, "\t. error\n");
345: else
346: {
347: for (; p; p = p->next)
348: {
349: if (p->action_code == REDUCE && p->number != defred)
350: {
351: k = p->number - 2;
352: if (p->suppressed == 0)
353: fprintf(verbose_file, "\t%s reduce %d\n",
354: symbol_name[p->symbol], k);
355: }
356: }
357:
358: if (defred > 0)
359: fprintf(verbose_file, "\t. reduce %d\n", defred - 2);
360: }
361: }
362:
363:
1.4 pvalchev 364: void
1.8 pvalchev 365: print_gotos(int stateno)
1.1 deraadt 366: {
1.5 mpech 367: int i, k;
368: int as;
369: short *to_state;
370: shifts *sp;
1.1 deraadt 371:
372: putc('\n', verbose_file);
373: sp = shift_table[stateno];
374: to_state = sp->shift;
375: for (i = 0; i < sp->nshifts; ++i)
376: {
377: k = to_state[i];
378: as = accessing_symbol[k];
379: if (ISVAR(as))
380: fprintf(verbose_file, "\t%s goto %d\n", symbol_name[as], k);
381: }
382: }