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