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