]> git.saurik.com Git - bison.git/blame - src/print.c
* src/print.c (print_actions): Better locality of variables.
[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 fputs ("\n\n", out);
185 fprintf (out, _("state %d"), state);
186 fputs ("\n\n", out);
187 print_core (out, state);
188 print_actions (out, state);
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 */
0df87bb6 215 fprintf (out, "\n%s\n\n", _("Grammar"));
e06f0c34
RS
216 for (i = 1; i <= nrules; i++)
217 /* Don't print rules disabled in reduce_grammar_tables. */
b2ed6e58 218 if (rule_table[i].lhs >= 0)
e06f0c34 219 {
b2ed6e58
AD
220 fprintf (out, _("rule %-4d %s ->"), i, tags[rule_table[i].lhs]);
221 rule = &ritem[rule_table[i].rhs];
e06f0c34
RS
222 if (*rule > 0)
223 while (*rule > 0)
342b8b6e 224 fprintf (out, " %s", tags[*rule++]);
e06f0c34 225 else
0df87bb6
AD
226 fprintf (out, " /* %s */", _("empty"));
227 fputc ('\n', out);
e06f0c34
RS
228 }
229
230 /* TERMINAL (type #) : rule #s terminal is on RHS */
342b8b6e
AD
231 fprintf (out, "\n%s\n\n", _("Terminals, with rules where they appear"));
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 }
253
254 fprintf (out, "\n%s\n\n",
255 _("Nonterminals, with rules where they appear"));
e06f0c34
RS
256 for (i = ntokens; i <= nsyms - 1; i++)
257 {
258 int left_count = 0, right_count = 0;
259
260 for (j = 1; j <= nrules; j++)
261 {
b2ed6e58 262 if (rule_table[j].lhs == i)
e06f0c34 263 left_count++;
b2ed6e58 264 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
e06f0c34
RS
265 if (*rule == i)
266 {
267 right_count++;
268 break;
269 }
270 }
271
272 buffer[0] = 0;
342b8b6e 273 fputs (tags[i], out);
e06f0c34
RS
274 column = strlen (tags[i]);
275 sprintf (buffer, " (%d)", i);
276 END_TEST (0);
277
278 if (left_count > 0)
279 {
280 END_TEST (50);
c29240e7 281 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34
RS
282
283 for (j = 1; j <= nrules; j++)
284 {
285 END_TEST (65);
b2ed6e58 286 if (rule_table[j].lhs == i)
c29240e7 287 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
288 }
289 }
290
291 if (right_count > 0)
292 {
293 if (left_count > 0)
c29240e7 294 sprintf (buffer + strlen (buffer), ",");
e06f0c34 295 END_TEST (50);
c29240e7 296 sprintf (buffer + strlen (buffer), _(" on right:"));
e06f0c34
RS
297 for (j = 1; j <= nrules; j++)
298 {
b2ed6e58 299 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
e06f0c34
RS
300 if (*rule == i)
301 {
302 END_TEST (65);
c29240e7 303 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
304 break;
305 }
306 }
307 }
342b8b6e 308 fprintf (out, "%s\n", buffer);
e06f0c34
RS
309 }
310}
07a58c13
AD
311\f
312void
313print_results (void)
314{
342b8b6e
AD
315 if (verbose_flag)
316 {
317 int i;
07a58c13 318
342b8b6e
AD
319 /* We used to use just .out if spec_name_prefix (-p) was used, but
320 that conflicts with Posix. */
321 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 322
342b8b6e
AD
323 size_t size = obstack_object_size (&output_obstack);
324 fwrite (obstack_finish (&output_obstack), 1, size, out);
07a58c13 325
337c5bd1 326 reduce_output (out);
0df87bb6 327 conflicts_output (out);
342b8b6e
AD
328
329 print_grammar (out);
330
331 for (i = 0; i < nstates; i++)
332 print_state (out, i);
333
334 xfclose (out);
335 }
336 obstack_free (&output_obstack, NULL);
07a58c13 337}