]> git.saurik.com Git - bison.git/blob - src/print.c
Attaching lineno to buckets is stupid, since only one copy of each
[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 fputs ("\n\n", out);
185 fprintf (out, _("state %d"), state);
186 fputs ("\n\n", out);
187 print_core (out, state);
188 print_actions (out, state);
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, "\n%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].lhs >= 0)
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
232 /* TERMINAL (type #) : rule #s terminal is on RHS */
233 fprintf (out, "\n%s\n\n", _("Terminals, with rules where they appear"));
234 fprintf (out, "%s (-1)\n", tags[0]);
235
236 for (i = 0; i <= max_user_token_number; i++)
237 if (token_translations[i] != 2)
238 {
239 buffer[0] = 0;
240 column = strlen (tags[token_translations[i]]);
241 fputs (tags[token_translations[i]], out);
242 END_TEST (50);
243 sprintf (buffer, " (%d)", i);
244
245 for (j = 1; j <= nrules; j++)
246 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
247 if (*rule == token_translations[i])
248 {
249 END_TEST (65);
250 sprintf (buffer + strlen (buffer), " %d", j);
251 break;
252 }
253 fprintf (out, "%s\n", buffer);
254 }
255
256 fprintf (out, "\n%s\n\n",
257 _("Nonterminals, with rules where they appear"));
258 for (i = ntokens; i <= nsyms - 1; i++)
259 {
260 int left_count = 0, right_count = 0;
261
262 for (j = 1; j <= nrules; j++)
263 {
264 if (rule_table[j].lhs == i)
265 left_count++;
266 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
267 if (*rule == i)
268 {
269 right_count++;
270 break;
271 }
272 }
273
274 buffer[0] = 0;
275 fputs (tags[i], out);
276 column = strlen (tags[i]);
277 sprintf (buffer, " (%d)", i);
278 END_TEST (0);
279
280 if (left_count > 0)
281 {
282 END_TEST (50);
283 sprintf (buffer + strlen (buffer), _(" on left:"));
284
285 for (j = 1; j <= nrules; j++)
286 {
287 END_TEST (65);
288 if (rule_table[j].lhs == i)
289 sprintf (buffer + strlen (buffer), " %d", j);
290 }
291 }
292
293 if (right_count > 0)
294 {
295 if (left_count > 0)
296 sprintf (buffer + strlen (buffer), ",");
297 END_TEST (50);
298 sprintf (buffer + strlen (buffer), _(" on right:"));
299 for (j = 1; j <= nrules; j++)
300 {
301 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
302 if (*rule == i)
303 {
304 END_TEST (65);
305 sprintf (buffer + strlen (buffer), " %d", j);
306 break;
307 }
308 }
309 }
310 fprintf (out, "%s\n", buffer);
311 }
312 }
313 \f
314 void
315 print_results (void)
316 {
317 if (verbose_flag)
318 {
319 int i;
320
321 /* We used to use just .out if spec_name_prefix (-p) was used, but
322 that conflicts with Posix. */
323 FILE *out = xfopen (spec_verbose_file, "w");
324
325 size_t size = obstack_object_size (&output_obstack);
326 fwrite (obstack_finish (&output_obstack), 1, size, out);
327
328 reduce_output (out);
329 conflicts_output (out);
330
331 print_grammar (out);
332
333 for (i = 0; i < nstates; i++)
334 print_state (out, i);
335
336 xfclose (out);
337 }
338 obstack_free (&output_obstack, NULL);
339 }