]> git.saurik.com Git - bison.git/blame - src/print.c
Pessimize the code to simplify it: from now on, all the states
[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 88 int i;
e06f0c34 89
d9ec2d07
AD
90 shifts *shiftp = state_table[state].shift_table;
91 reductions *redp = state_table[state].reduction_table;
92 errs *errp = err_table[state];
e06f0c34 93
d954473d 94 if (!shiftp->nshifts && !redp)
e06f0c34
RS
95 {
96 if (final_state == state)
342b8b6e 97 fprintf (out, _(" $default\taccept\n"));
e06f0c34 98 else
342b8b6e 99 fprintf (out, _(" NO ACTIONS\n"));
e06f0c34
RS
100 return;
101 }
102
d954473d
AD
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 }
e06f0c34 119
d954473d
AD
120 if (i > 0)
121 fputc ('\n', out);
e06f0c34
RS
122
123 if (errp)
124 {
d9ec2d07
AD
125 int j;
126 for (j = 0; j < errp->nerrs; j++)
e06f0c34 127 {
d9ec2d07
AD
128 int symbol = errp->errs[j];
129 if (!symbol)
c29240e7 130 continue;
342b8b6e 131 fprintf (out, _(" %-4s\terror (nonassociative)\n"),
c29240e7 132 tags[symbol]);
e06f0c34
RS
133 }
134
135 if (j > 0)
342b8b6e 136 fputc ('\n', out);
e06f0c34
RS
137 }
138
de326cc0 139 if (state_table[state].consistent && redp)
e06f0c34 140 {
d9ec2d07
AD
141 int rule = redp->rules[0];
142 int symbol = rule_table[rule].lhs;
342b8b6e
AD
143 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
144 rule, tags[symbol]);
e06f0c34
RS
145 }
146 else if (redp)
147 {
c73a41af 148 print_reductions (out, state);
e06f0c34
RS
149 }
150
d954473d 151 if (i < shiftp->nshifts)
e06f0c34 152 {
d954473d
AD
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 }
e06f0c34 161
342b8b6e 162 fputc ('\n', out);
e06f0c34
RS
163 }
164}
165
07a58c13 166static void
342b8b6e 167print_state (FILE *out, int state)
07a58c13 168{
342b8b6e
AD
169 fprintf (out, _("state %d"), state);
170 fputs ("\n\n", out);
171 print_core (out, state);
172 print_actions (out, state);
d2d1b42b 173 fputs ("\n\n", out);
07a58c13
AD
174}
175\f
176/*-----------------------------------------.
177| Print information on the whole grammar. |
178`-----------------------------------------*/
179
342b8b6e
AD
180#define END_TEST(End) \
181do { \
182 if (column + strlen(buffer) > (End)) \
183 { \
184 fprintf (out, "%s\n ", buffer); \
185 column = 3; \
186 buffer[0] = 0; \
187 } \
ff4423cc 188} while (0)
e06f0c34 189
07a58c13 190
4a120d45 191static void
342b8b6e 192print_grammar (FILE *out)
e06f0c34
RS
193{
194 int i, j;
c29240e7 195 short *rule;
e06f0c34
RS
196 char buffer[90];
197 int column = 0;
198
199 /* rule # : LHS -> RHS */
d2d1b42b 200 fprintf (out, "%s\n\n", _("Grammar"));
b29b2ed5 201 fprintf (out, " %s\n", _("Number, Line, Rule"));
e06f0c34
RS
202 for (i = 1; i <= nrules; i++)
203 /* Don't print rules disabled in reduce_grammar_tables. */
68f1e3ed 204 if (rule_table[i].useful)
e06f0c34 205 {
b29b2ed5
AD
206 fprintf (out, _(" %3d %3d %s ->"),
207 i, rule_table[i].line, tags[rule_table[i].lhs]);
b2ed6e58 208 rule = &ritem[rule_table[i].rhs];
e06f0c34
RS
209 if (*rule > 0)
210 while (*rule > 0)
342b8b6e 211 fprintf (out, " %s", tags[*rule++]);
e06f0c34 212 else
b29b2ed5 213 fprintf (out, " /* %s */", _("empty"));
0df87bb6 214 fputc ('\n', out);
e06f0c34 215 }
d2d1b42b
AD
216 fputs ("\n\n", out);
217
e06f0c34
RS
218
219 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 220 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
342b8b6e 221 fprintf (out, "%s (-1)\n", tags[0]);
e06f0c34 222
342b8b6e
AD
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);
e06f0c34 231
342b8b6e 232 for (j = 1; j <= nrules; j++)
b2ed6e58 233 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
342b8b6e
AD
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 }
d2d1b42b
AD
242 fputs ("\n\n", out);
243
342b8b6e 244
d2d1b42b 245 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
e06f0c34
RS
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 {
b2ed6e58 252 if (rule_table[j].lhs == i)
e06f0c34 253 left_count++;
b2ed6e58 254 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
e06f0c34
RS
255 if (*rule == i)
256 {
257 right_count++;
258 break;
259 }
260 }
261
262 buffer[0] = 0;
342b8b6e 263 fputs (tags[i], out);
e06f0c34
RS
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);
c29240e7 271 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34
RS
272
273 for (j = 1; j <= nrules; j++)
274 {
275 END_TEST (65);
b2ed6e58 276 if (rule_table[j].lhs == i)
c29240e7 277 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
278 }
279 }
280
281 if (right_count > 0)
282 {
283 if (left_count > 0)
c29240e7 284 sprintf (buffer + strlen (buffer), ",");
e06f0c34 285 END_TEST (50);
c29240e7 286 sprintf (buffer + strlen (buffer), _(" on right:"));
e06f0c34
RS
287 for (j = 1; j <= nrules; j++)
288 {
b2ed6e58 289 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
e06f0c34
RS
290 if (*rule == i)
291 {
292 END_TEST (65);
c29240e7 293 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
294 break;
295 }
296 }
297 }
342b8b6e 298 fprintf (out, "%s\n", buffer);
e06f0c34 299 }
d2d1b42b 300 fputs ("\n\n", out);
e06f0c34 301}
07a58c13
AD
302\f
303void
304print_results (void)
305{
342b8b6e
AD
306 if (verbose_flag)
307 {
308 int i;
07a58c13 309
342b8b6e
AD
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");
07a58c13 313
342b8b6e
AD
314 size_t size = obstack_object_size (&output_obstack);
315 fwrite (obstack_finish (&output_obstack), 1, size, out);
d2d1b42b
AD
316 if (size)
317 fputs ("\n\n", out);
07a58c13 318
337c5bd1 319 reduce_output (out);
0df87bb6 320 conflicts_output (out);
342b8b6e
AD
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);
07a58c13 330}