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