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