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