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