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