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