]> git.saurik.com Git - bison.git/blame - src/print.c
* src/state.h, src/state.c (reductions_new): New.
[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
5092aba5
AD
35static unsigned *shiftset = NULL;
36static unsigned *lookaheadset = NULL;
37
07a58c13 38#if 0
4a120d45 39static void
d2729d44 40print_token (int extnum, int token)
e06f0c34 41{
342b8b6e 42 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 43}
4a120d45 44#endif
e06f0c34 45
07a58c13 46\f
342b8b6e 47/*--------------------------------.
07a58c13 48| Report information on a state. |
342b8b6e 49`--------------------------------*/
e06f0c34 50
4a120d45 51static void
065fbd27 52print_core (FILE *out, state_t *state)
e06f0c34 53{
c29240e7 54 int i;
065fbd27
AD
55 short *sitems = state->items;
56 int snitems = state->nitems;
e06f0c34 57
43168960
AD
58 /* New experimental feature: if TRACE_FLAGS output all the items of
59 a state, not only its kernel. */
60 if (trace_flag)
61 {
62 closure (sitems, snitems);
63 sitems = itemset;
64 snitems = nitemset;
65 }
e06f0c34 66
43168960 67 if (snitems)
e06f0c34 68 {
43168960
AD
69 for (i = 0; i < snitems; i++)
70 {
71 short *sp;
72 short *sp1;
73 int rule;
4bc30f78 74
43168960 75 sp1 = sp = ritem + sitems[i];
e06f0c34 76
43168960
AD
77 while (*sp > 0)
78 sp++;
e06f0c34 79
43168960
AD
80 rule = -(*sp);
81 fprintf (out, " %s -> ", tags[rule_table[rule].lhs]);
e06f0c34 82
43168960
AD
83 for (sp = ritem + rule_table[rule].rhs; sp < sp1; sp++)
84 fprintf (out, "%s ", tags[*sp]);
e06f0c34 85
43168960 86 fputc ('.', out);
e06f0c34 87
43168960
AD
88 for (/* Nothing */; *sp > 0; ++sp)
89 fprintf (out, " %s", tags[*sp]);
90
91 fprintf (out, _(" (rule %d)"), rule);
92 fputc ('\n', out);
93 }
e06f0c34 94
342b8b6e 95 fputc ('\n', out);
e06f0c34 96 }
e06f0c34
RS
97}
98
5092aba5 99
4a120d45 100static void
5092aba5 101print_shifts (FILE *out, state_t *state)
e06f0c34 102{
c29240e7 103 int i;
5092aba5 104 shifts *shiftp = state->shifts;
e06f0c34 105
2e729273 106 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
d954473d
AD
107 if (!SHIFT_IS_DISABLED (shiftp, i))
108 {
109 int state1 = shiftp->shifts[i];
f693ad14 110 int symbol = state_table[state1]->accessing_symbol;
2e729273
AD
111 fprintf (out,
112 _(" %-4s\tshift, and go to state %d\n"),
113 tags[symbol], state1);
d954473d 114 }
e06f0c34 115
d954473d
AD
116 if (i > 0)
117 fputc ('\n', out);
5092aba5 118}
e06f0c34 119
e06f0c34 120
5092aba5
AD
121static void
122print_errs (FILE *out, state_t *state)
123{
124 errs *errp = state->errs;
125 int i;
126
5092aba5
AD
127 for (i = 0; i < errp->nerrs; ++i)
128 if (errp->errs[i])
129 fprintf (out, _(" %-4s\terror (nonassociative)\n"),
130 tags[errp->errs[i]]);
131
132 if (i > 0)
2cec70b9 133 fputc ('\n', out);
5092aba5 134}
e06f0c34 135
5092aba5
AD
136
137static void
138print_gotos (FILE *out, state_t *state)
139{
140 int i;
141 shifts *shiftp = state->shifts;
142
143 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
144 /* Skip token shifts. */;
e06f0c34 145
d954473d 146 if (i < shiftp->nshifts)
e06f0c34 147 {
d954473d
AD
148 for (; i < shiftp->nshifts; i++)
149 if (!SHIFT_IS_DISABLED (shiftp, i))
150 {
151 int state1 = shiftp->shifts[i];
f693ad14 152 int symbol = state_table[state1]->accessing_symbol;
d954473d
AD
153 fprintf (out, _(" %-4s\tgo to state %d\n"),
154 tags[symbol], state1);
155 }
e06f0c34 156
342b8b6e 157 fputc ('\n', out);
e06f0c34
RS
158 }
159}
160
5092aba5
AD
161static void
162print_reductions (FILE *out, state_t *state)
163{
164 int i;
165 shifts *shiftp = state->shifts;
166 reductions *redp = state->reductions;
167 errs *errp = state->errs;
168 int nodefault = 0;
169
80dac38c
AD
170 if (redp->nreds == 0)
171 return;
172
5092aba5
AD
173 if (state->consistent)
174 {
175 int rule = redp->rules[0];
176 int symbol = rule_table[rule].lhs;
177 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
178 rule, tags[symbol]);
179 return;
180 }
181
182 for (i = 0; i < tokensetsize; i++)
183 shiftset[i] = 0;
184
185 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
186 if (!SHIFT_IS_DISABLED (shiftp, i))
187 {
188 /* if this state has a shift for the error token, don't use a
189 default rule. */
190 if (SHIFT_IS_ERROR (shiftp, i))
191 nodefault = 1;
192 SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
193 }
194
2cec70b9
AD
195 for (i = 0; i < errp->nerrs; i++)
196 if (errp->errs[i])
197 SETBIT (shiftset, errp->errs[i]);
5092aba5
AD
198
199 if (state->nlookaheads == 1 && !nodefault)
200 {
201 int k;
202 int default_rule = LAruleno[state->lookaheadsp];
203
204 for (k = 0; k < tokensetsize; ++k)
205 lookaheadset[k] = LA (state->lookaheadsp)[k] & shiftset[k];
206
207 for (i = 0; i < ntokens; i++)
208 if (BITISSET (lookaheadset, i))
209 fprintf (out, _(" %-4s\t[reduce using rule %d (%s)]\n"),
210 tags[i], default_rule,
211 tags[rule_table[default_rule].lhs]);
212
213 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
214 default_rule, tags[rule_table[default_rule].lhs]);
215 }
216 else if (state->nlookaheads >= 1)
217 {
218 int cmax = 0;
219 int default_LA = -1;
220 int default_rule = 0;
221
222 if (!nodefault)
223 for (i = 0; i < state->nlookaheads; ++i)
224 {
225 int count = 0;
226 int j, k;
227
228 for (k = 0; k < tokensetsize; ++k)
229 lookaheadset[k] = LA (state->lookaheadsp + i)[k] & ~shiftset[k];
230
231 for (j = 0; j < ntokens; j++)
232 if (BITISSET (lookaheadset, j))
233 count++;
234
235 if (count > cmax)
236 {
237 cmax = count;
238 default_LA = state->lookaheadsp + i;
239 default_rule = LAruleno[state->lookaheadsp + i];
240 }
241
242 for (k = 0; k < tokensetsize; ++k)
243 shiftset[k] |= lookaheadset[k];
244 }
245
246 for (i = 0; i < tokensetsize; i++)
247 shiftset[i] = 0;
248
249 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
250 if (!SHIFT_IS_DISABLED (shiftp, i))
251 SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
252
253 for (i = 0; i < ntokens; i++)
254 {
255 int j;
256 int defaulted = 0;
257 int count = BITISSET (shiftset, i);
258
259 for (j = 0; j < state->nlookaheads; ++j)
260 {
261 if (BITISSET (LA (state->lookaheadsp + j), i))
262 {
263 if (count == 0)
264 {
265 if (state->lookaheadsp + j != default_LA)
266 fprintf (out,
267 _(" %-4s\treduce using rule %d (%s)\n"),
268 tags[i],
269 LAruleno[state->lookaheadsp + j],
270 tags[rule_table[LAruleno[state->lookaheadsp + j]].lhs]);
271 else
272 defaulted = 1;
273
274 count++;
275 }
276 else
277 {
278 if (defaulted)
279 fprintf (out,
280 _(" %-4s\treduce using rule %d (%s)\n"),
281 tags[i],
282 LAruleno[default_LA],
283 tags[rule_table[LAruleno[default_LA]].lhs]);
284 defaulted = 0;
285 fprintf (out,
286 _(" %-4s\t[reduce using rule %d (%s)]\n"),
287 tags[i],
288 LAruleno[state->lookaheadsp + j],
289 tags[rule_table[LAruleno[state->lookaheadsp + j]].lhs]);
290 }
291 }
292 }
293 }
294
295 if (default_LA >= 0)
296 fprintf (out, _(" $default\treduce using rule %d (%s)\n"),
297 default_rule, tags[rule_table[default_rule].lhs]);
298 }
299}
300
301
302static void
303print_actions (FILE *out, state_t *state)
304{
305 reductions *redp = state->reductions;
306 shifts *shiftp = state->shifts;
307
80dac38c 308 if (shiftp->nshifts == 0 && redp->nreds == 0)
5092aba5
AD
309 {
310 if (final_state == state->number)
311 fprintf (out, _(" $default\taccept\n"));
312 else
313 fprintf (out, _(" NO ACTIONS\n"));
314 return;
315 }
316
317 print_shifts (out, state);
318 print_errs (out, state);
80dac38c 319 print_reductions (out, state);
5092aba5
AD
320 print_gotos (out, state);
321}
322
07a58c13 323static void
065fbd27 324print_state (FILE *out, state_t *state)
07a58c13 325{
065fbd27 326 fprintf (out, _("state %d"), state->number);
342b8b6e
AD
327 fputs ("\n\n", out);
328 print_core (out, state);
329 print_actions (out, state);
d2d1b42b 330 fputs ("\n\n", out);
07a58c13
AD
331}
332\f
333/*-----------------------------------------.
334| Print information on the whole grammar. |
335`-----------------------------------------*/
336
342b8b6e
AD
337#define END_TEST(End) \
338do { \
339 if (column + strlen(buffer) > (End)) \
340 { \
341 fprintf (out, "%s\n ", buffer); \
342 column = 3; \
343 buffer[0] = 0; \
344 } \
ff4423cc 345} while (0)
e06f0c34 346
07a58c13 347
4a120d45 348static void
342b8b6e 349print_grammar (FILE *out)
e06f0c34
RS
350{
351 int i, j;
c29240e7 352 short *rule;
e06f0c34
RS
353 char buffer[90];
354 int column = 0;
355
356 /* rule # : LHS -> RHS */
d2d1b42b 357 fprintf (out, "%s\n\n", _("Grammar"));
b29b2ed5 358 fprintf (out, " %s\n", _("Number, Line, Rule"));
e06f0c34
RS
359 for (i = 1; i <= nrules; i++)
360 /* Don't print rules disabled in reduce_grammar_tables. */
68f1e3ed 361 if (rule_table[i].useful)
e06f0c34 362 {
b29b2ed5
AD
363 fprintf (out, _(" %3d %3d %s ->"),
364 i, rule_table[i].line, tags[rule_table[i].lhs]);
b2ed6e58 365 rule = &ritem[rule_table[i].rhs];
e06f0c34
RS
366 if (*rule > 0)
367 while (*rule > 0)
342b8b6e 368 fprintf (out, " %s", tags[*rule++]);
e06f0c34 369 else
b29b2ed5 370 fprintf (out, " /* %s */", _("empty"));
0df87bb6 371 fputc ('\n', out);
e06f0c34 372 }
d2d1b42b
AD
373 fputs ("\n\n", out);
374
e06f0c34
RS
375
376 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 377 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
342b8b6e 378 fprintf (out, "%s (-1)\n", tags[0]);
e06f0c34 379
342b8b6e
AD
380 for (i = 0; i <= max_user_token_number; i++)
381 if (token_translations[i] != 2)
382 {
383 buffer[0] = 0;
384 column = strlen (tags[token_translations[i]]);
385 fputs (tags[token_translations[i]], out);
386 END_TEST (50);
387 sprintf (buffer, " (%d)", i);
e06f0c34 388
342b8b6e 389 for (j = 1; j <= nrules; j++)
b2ed6e58 390 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
342b8b6e
AD
391 if (*rule == token_translations[i])
392 {
393 END_TEST (65);
394 sprintf (buffer + strlen (buffer), " %d", j);
395 break;
396 }
397 fprintf (out, "%s\n", buffer);
398 }
d2d1b42b
AD
399 fputs ("\n\n", out);
400
342b8b6e 401
d2d1b42b 402 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
e06f0c34
RS
403 for (i = ntokens; i <= nsyms - 1; i++)
404 {
405 int left_count = 0, right_count = 0;
406
407 for (j = 1; j <= nrules; j++)
408 {
b2ed6e58 409 if (rule_table[j].lhs == i)
e06f0c34 410 left_count++;
b2ed6e58 411 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
e06f0c34
RS
412 if (*rule == i)
413 {
414 right_count++;
415 break;
416 }
417 }
418
419 buffer[0] = 0;
342b8b6e 420 fputs (tags[i], out);
e06f0c34
RS
421 column = strlen (tags[i]);
422 sprintf (buffer, " (%d)", i);
423 END_TEST (0);
424
425 if (left_count > 0)
426 {
427 END_TEST (50);
c29240e7 428 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34
RS
429
430 for (j = 1; j <= nrules; j++)
431 {
432 END_TEST (65);
b2ed6e58 433 if (rule_table[j].lhs == i)
c29240e7 434 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
435 }
436 }
437
438 if (right_count > 0)
439 {
440 if (left_count > 0)
c29240e7 441 sprintf (buffer + strlen (buffer), ",");
e06f0c34 442 END_TEST (50);
c29240e7 443 sprintf (buffer + strlen (buffer), _(" on right:"));
e06f0c34
RS
444 for (j = 1; j <= nrules; j++)
445 {
b2ed6e58 446 for (rule = &ritem[rule_table[j].rhs]; *rule > 0; rule++)
e06f0c34
RS
447 if (*rule == i)
448 {
449 END_TEST (65);
c29240e7 450 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
451 break;
452 }
453 }
454 }
342b8b6e 455 fprintf (out, "%s\n", buffer);
e06f0c34 456 }
d2d1b42b 457 fputs ("\n\n", out);
e06f0c34 458}
07a58c13
AD
459\f
460void
461print_results (void)
462{
64d15509 463 int i;
07a58c13 464
64d15509
AD
465 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
466 that conflicts with Posix. */
467 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 468
64d15509
AD
469 size_t size = obstack_object_size (&output_obstack);
470 fwrite (obstack_finish (&output_obstack), 1, size, out);
471 obstack_free (&output_obstack, NULL);
07a58c13 472
64d15509
AD
473 if (size)
474 fputs ("\n\n", out);
342b8b6e 475
64d15509
AD
476 reduce_output (out);
477 conflicts_output (out);
342b8b6e 478
64d15509 479 print_grammar (out);
342b8b6e 480
5092aba5
AD
481 /* New experimental feature: output all the items of a state, not
482 only its kernel. Requires to run closure, which need memory
483 allocation/deallocation. */
64d15509
AD
484 if (trace_flag)
485 new_closure (nitems);
5092aba5
AD
486 /* Storage for print_reductions. */
487 shiftset = XCALLOC (unsigned, tokensetsize);
488 lookaheadset = XCALLOC (unsigned, tokensetsize);
64d15509 489 for (i = 0; i < nstates; i++)
065fbd27 490 print_state (out, state_table[i]);
5092aba5
AD
491 free (shiftset);
492 free (lookaheadset);
64d15509
AD
493 if (trace_flag)
494 free_closure ();
495
496 xfclose (out);
07a58c13 497}