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