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