]> git.saurik.com Git - bison.git/blob - src/print.c
ff6803d431494aea8970ebd60a3826959550df1f
[bison.git] / src / print.c
1 /* Print information on generated parser, for bison,
2 Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
3
4 This file is part of Bison, the GNU Compiler Compiler.
5
6 Bison is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 Bison is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 #include <stdio.h>
23 #include "system.h"
24 #include "machine.h"
25 #include "alloc.h"
26 #include "files.h"
27 #include "gram.h"
28 #include "state.h"
29
30
31 extern char **tags;
32 extern int nstates;
33 extern short *accessing_symbol;
34 extern core **state_table;
35 extern shifts **shift_table;
36 extern errs **err_table;
37 extern reductions **reduction_table;
38 extern char *consistent;
39 extern char any_conflicts;
40 extern char *conflicts;
41 extern int final_state;
42
43 extern void conflict_log PARAMS((void));
44 extern void verbose_conflict_log PARAMS((void));
45 extern void print_reductions PARAMS((int));
46
47 extern void terse PARAMS((void));
48 extern void verbose PARAMS((void));
49
50 #if 0 /* XXX currently unused. */
51 static void print_token PARAMS((int, int));
52 #endif
53
54 static void print_state PARAMS((int));
55 static void print_core PARAMS((int));
56 static void print_actions PARAMS((int));
57 static void print_grammar PARAMS((void));
58
59 void
60 terse (void)
61 {
62 if (any_conflicts)
63 {
64 conflict_log();
65 }
66 }
67
68
69 void
70 verbose (void)
71 {
72 register int i;
73
74 if (any_conflicts)
75 verbose_conflict_log();
76
77 print_grammar();
78
79 for (i = 0; i < nstates; i++)
80 {
81 print_state(i);
82 }
83 }
84
85
86 #if 0 /* XXX currently unused. */
87 static void
88 print_token (int extnum, int token)
89 {
90 fprintf(foutput, _(" type %d is %s\n"), extnum, tags[token]);
91 }
92 #endif
93
94
95 static void
96 print_state (int state)
97 {
98 fprintf(foutput, _("\n\nstate %d\n\n"), state);
99 print_core(state);
100 print_actions(state);
101 }
102
103
104 static void
105 print_core (int state)
106 {
107 register int i;
108 register int k;
109 register int rule;
110 register core *statep;
111 register short *sp;
112 register short *sp1;
113
114 statep = state_table[state];
115 k = statep->nitems;
116
117 if (k == 0) return;
118
119 for (i = 0; i < k; i++)
120 {
121 sp1 = sp = ritem + statep->items[i];
122
123 while (*sp > 0)
124 sp++;
125
126 rule = -(*sp);
127 fprintf(foutput, " %s -> ", tags[rlhs[rule]]);
128
129 for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
130 {
131 fprintf(foutput, "%s ", tags[*sp]);
132 }
133
134 putc('.', foutput);
135
136 while (*sp > 0)
137 {
138 fprintf(foutput, " %s", tags[*sp]);
139 sp++;
140 }
141
142 fprintf (foutput, _(" (rule %d)"), rule);
143 putc('\n', foutput);
144 }
145
146 putc('\n', foutput);
147 }
148
149
150 static void
151 print_actions (int state)
152 {
153 register int i;
154 register int k;
155 register int state1;
156 register int symbol;
157 register shifts *shiftp;
158 register errs *errp;
159 register reductions *redp;
160 register int rule;
161
162 shiftp = shift_table[state];
163 redp = reduction_table[state];
164 errp = err_table[state];
165
166 if (!shiftp && !redp)
167 {
168 if (final_state == state)
169 fprintf(foutput, _(" $default\taccept\n"));
170 else
171 fprintf(foutput, _(" NO ACTIONS\n"));
172 return;
173 }
174
175 if (shiftp)
176 {
177 k = shiftp->nshifts;
178
179 for (i = 0; i < k; i++)
180 {
181 if (! shiftp->shifts[i]) continue;
182 state1 = shiftp->shifts[i];
183 symbol = accessing_symbol[state1];
184 /* The following line used to be turned off. */
185 if (ISVAR(symbol)) break;
186 if (symbol==0) /* I.e. strcmp(tags[symbol],"$")==0 */
187 fprintf(foutput, _(" $ \tgo to state %d\n"), state1);
188 else
189 fprintf(foutput, _(" %-4s\tshift, and go to state %d\n"),
190 tags[symbol], state1);
191 }
192
193 if (i > 0)
194 putc('\n', foutput);
195 }
196 else
197 {
198 i = 0;
199 k = 0;
200 }
201
202 if (errp)
203 {
204 int j, nerrs;
205
206 nerrs = errp->nerrs;
207
208 for (j = 0; j < nerrs; j++)
209 {
210 if (! errp->errs[j]) continue;
211 symbol = errp->errs[j];
212 fprintf(foutput, _(" %-4s\terror (nonassociative)\n"), tags[symbol]);
213 }
214
215 if (j > 0)
216 putc('\n', foutput);
217 }
218
219 if (consistent[state] && redp)
220 {
221 rule = redp->rules[0];
222 symbol = rlhs[rule];
223 fprintf(foutput, _(" $default\treduce using rule %d (%s)\n\n"),
224 rule, tags[symbol]);
225 }
226 else if (redp)
227 {
228 print_reductions(state);
229 }
230
231 if (i < k)
232 {
233 for (; i < k; i++)
234 {
235 if (! shiftp->shifts[i]) continue;
236 state1 = shiftp->shifts[i];
237 symbol = accessing_symbol[state1];
238 fprintf(foutput, _(" %-4s\tgo to state %d\n"), tags[symbol], state1);
239 }
240
241 putc('\n', foutput);
242 }
243 }
244
245 #define END_TEST(end) \
246 do { \
247 if (column + strlen(buffer) > (end)) { \
248 fprintf (foutput, "%s\n ", buffer); \
249 column = 3; \
250 buffer[0] = 0; \
251 } \
252 } while (0)
253
254 static void
255 print_grammar (void)
256 {
257 int i, j;
258 short* rule;
259 char buffer[90];
260 int column = 0;
261
262 /* rule # : LHS -> RHS */
263 fputs(_("\nGrammar\n"), foutput);
264 for (i = 1; i <= nrules; i++)
265 /* Don't print rules disabled in reduce_grammar_tables. */
266 if (rlhs[i] >= 0)
267 {
268 fprintf(foutput, _("rule %-4d %s ->"), i, tags[rlhs[i]]);
269 rule = &ritem[rrhs[i]];
270 if (*rule > 0)
271 while (*rule > 0)
272 fprintf(foutput, " %s", tags[*rule++]);
273 else
274 fputs (_(" /* empty */"), foutput);
275 putc('\n', foutput);
276 }
277
278 /* TERMINAL (type #) : rule #s terminal is on RHS */
279 fputs(_("\nTerminals, with rules where they appear\n\n"), foutput);
280 fprintf(foutput, "%s (-1)\n", tags[0]);
281 if (translations)
282 {
283 for (i = 0; i <= max_user_token_number; i++)
284 if (token_translations[i] != 2)
285 {
286 buffer[0] = 0;
287 column = strlen (tags[token_translations[i]]);
288 fprintf(foutput, "%s", tags[token_translations[i]]);
289 END_TEST (50);
290 sprintf (buffer, " (%d)", i);
291
292 for (j = 1; j <= nrules; j++)
293 {
294 for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
295 if (*rule == token_translations[i])
296 {
297 END_TEST (65);
298 sprintf (buffer + strlen(buffer), " %d", j);
299 break;
300 }
301 }
302 fprintf (foutput, "%s\n", buffer);
303 }
304 }
305 else
306 for (i = 1; i < ntokens; i++)
307 {
308 buffer[0] = 0;
309 column = strlen (tags[i]);
310 fprintf(foutput, "%s", tags[i]);
311 END_TEST (50);
312 sprintf (buffer, " (%d)", i);
313
314 for (j = 1; j <= nrules; j++)
315 {
316 for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
317 if (*rule == i)
318 {
319 END_TEST (65);
320 sprintf (buffer + strlen(buffer), " %d", j);
321 break;
322 }
323 }
324 fprintf (foutput, "%s\n", buffer);
325 }
326
327 fputs(_("\nNonterminals, with rules where they appear\n\n"), foutput);
328 for (i = ntokens; i <= nsyms - 1; i++)
329 {
330 int left_count = 0, right_count = 0;
331
332 for (j = 1; j <= nrules; j++)
333 {
334 if (rlhs[j] == i)
335 left_count++;
336 for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
337 if (*rule == i)
338 {
339 right_count++;
340 break;
341 }
342 }
343
344 buffer[0] = 0;
345 fprintf(foutput, "%s", tags[i]);
346 column = strlen (tags[i]);
347 sprintf (buffer, " (%d)", i);
348 END_TEST (0);
349
350 if (left_count > 0)
351 {
352 END_TEST (50);
353 sprintf (buffer + strlen(buffer), _(" on left:"));
354
355 for (j = 1; j <= nrules; j++)
356 {
357 END_TEST (65);
358 if (rlhs[j] == i)
359 sprintf (buffer + strlen(buffer), " %d", j);
360 }
361 }
362
363 if (right_count > 0)
364 {
365 if (left_count > 0)
366 sprintf (buffer + strlen(buffer), ",");
367 END_TEST (50);
368 sprintf (buffer + strlen(buffer), _(" on right:"));
369 for (j = 1; j <= nrules; j++)
370 {
371 for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
372 if (*rule == i)
373 {
374 END_TEST (65);
375 sprintf (buffer + strlen(buffer), " %d", j);
376 break;
377 }
378 }
379 }
380 fprintf (foutput, "%s\n", buffer);
381 }
382 }