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