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