]> git.saurik.com Git - bison.git/blame - src/print.c
* src/files.c: Include "stdio-safer.h"; this fixes a typo in
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
a737b216 2
8dd162d3 3 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004
b0299a2e 4 Free Software Foundation, Inc.
e06f0c34 5
c29240e7 6 This file is part of Bison, the GNU Compiler Compiler.
e06f0c34 7
c29240e7
AD
8 Bison is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
e06f0c34 12
c29240e7
AD
13 Bison is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
e06f0c34 17
c29240e7
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to
0fb669f9
PE
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
e06f0c34
RS
22
23
e06f0c34 24#include "system.h"
17ee7397
PE
25
26#include <bitset.h>
27#include <quotearg.h>
28
b2ca4022 29#include "LR0.h"
17ee7397 30#include "closure.h"
0619caf0 31#include "conflicts.h"
17ee7397 32#include "files.h"
07a58c13 33#include "getargs.h"
17ee7397
PE
34#include "gram.h"
35#include "lalr.h"
d7913476 36#include "print.h"
17ee7397 37#include "reader.h"
09b503c8 38#include "reduce.h"
17ee7397
PE
39#include "state.h"
40#include "symtab.h"
e06f0c34 41
8dd162d3
PE
42static bitset shift_set;
43static bitset look_ahead_set;
5092aba5 44
07a58c13 45#if 0
4a120d45 46static void
d2729d44 47print_token (int extnum, int token)
e06f0c34 48{
342b8b6e 49 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 50}
4a120d45 51#endif
e06f0c34 52
07a58c13 53\f
87675353
AD
54
55/*---------------------------------------.
56| *WIDTH := max (*WIDTH, strlen (STR)). |
57`---------------------------------------*/
58
59static void
60max_length (size_t *width, const char *str)
61{
62 size_t len = strlen (str);
63 if (len > *width)
64 *width = len;
65}
66
342b8b6e 67/*--------------------------------.
07a58c13 68| Report information on a state. |
342b8b6e 69`--------------------------------*/
e06f0c34 70
4a120d45 71static void
17ee7397 72print_core (FILE *out, state *s)
e06f0c34 73{
f6fbd3da 74 size_t i;
17ee7397 75 item_number *sitems = s->items;
f6fbd3da 76 size_t snritems = s->nitems;
17ee7397 77 symbol *previous_lhs = NULL;
e06f0c34 78
ec3bc396
AD
79 /* Output all the items of a state, not only its kernel. */
80 if (report_flag & report_itemsets)
43168960 81 {
5123689b 82 closure (sitems, snritems);
43168960 83 sitems = itemset;
5123689b 84 snritems = nritemset;
43168960 85 }
e06f0c34 86
ce4ccb4b
AD
87 if (!snritems)
88 return;
e06f0c34 89
87675353
AD
90 fputc ('\n', out);
91
ce4ccb4b
AD
92 for (i = 0; i < snritems; i++)
93 {
17ee7397
PE
94 item_number *sp;
95 item_number *sp1;
a737b216 96 rule_number r;
e06f0c34 97
ce4ccb4b 98 sp1 = sp = ritem + sitems[i];
e06f0c34 99
ce4ccb4b
AD
100 while (*sp >= 0)
101 sp++;
e06f0c34 102
17ee7397 103 r = item_number_as_rule_number (*sp);
e06f0c34 104
17ee7397
PE
105 rule_lhs_print (&rules[r], previous_lhs, out);
106 previous_lhs = rules[r].lhs;
43168960 107
17ee7397 108 for (sp = rules[r].rhs; sp < sp1; sp++)
97650f4e 109 fprintf (out, " %s", symbols[*sp]->tag);
ce4ccb4b
AD
110 fputs (" .", out);
111 for (/* Nothing */; *sp >= 0; ++sp)
97650f4e 112 fprintf (out, " %s", symbols[*sp]->tag);
d4e7d3a1 113
8dd162d3
PE
114 /* Display the look-ahead tokens? */
115 if (report_flag & report_look_ahead_tokens)
116 state_rule_look_ahead_tokens_print (s, &rules[r], out);
e06f0c34 117
342b8b6e 118 fputc ('\n', out);
e06f0c34 119 }
e06f0c34
RS
120}
121
5092aba5 122
17ee7397
PE
123/*------------------------------------------------------------.
124| Report the shifts iff DISPLAY_SHIFTS_P or the gotos of S on |
125| OUT. |
126`------------------------------------------------------------*/
87675353 127
4a120d45 128static void
17ee7397 129print_transitions (state *s, FILE *out, bool display_transitions_p)
e06f0c34 130{
17ee7397 131 transitions *trans = s->transitions;
87675353
AD
132 size_t width = 0;
133 int i;
e06f0c34 134
8dd162d3 135 /* Compute the width of the look-ahead token column. */
17ee7397
PE
136 for (i = 0; i < trans->num; i++)
137 if (!TRANSITION_IS_DISABLED (trans, i)
138 && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
d954473d 139 {
17ee7397
PE
140 symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
141 max_length (&width, sym->tag);
d954473d 142 }
e06f0c34 143
87675353
AD
144 /* Nothing to report. */
145 if (!width)
146 return;
147
148 fputc ('\n', out);
149 width += 2;
150
8dd162d3 151 /* Report look-ahead tokens and shifts. */
17ee7397
PE
152 for (i = 0; i < trans->num; i++)
153 if (!TRANSITION_IS_DISABLED (trans, i)
154 && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
87675353 155 {
17ee7397
PE
156 symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
157 const char *tag = sym->tag;
158 state *s1 = trans->states[i];
87675353
AD
159 int j;
160
161 fprintf (out, " %s", tag);
162 for (j = width - strlen (tag); j > 0; --j)
163 fputc (' ', out);
ccaf65bc 164 if (display_transitions_p)
17ee7397 165 fprintf (out, _("shift, and go to state %d\n"), s1->number);
87675353 166 else
17ee7397 167 fprintf (out, _("go to state %d\n"), s1->number);
87675353 168 }
5092aba5 169}
e06f0c34 170
e06f0c34 171
17ee7397
PE
172/*--------------------------------------------------------.
173| Report the explicit errors of S raised from %nonassoc. |
174`--------------------------------------------------------*/
87675353 175
5092aba5 176static void
17ee7397 177print_errs (FILE *out, state *s)
5092aba5 178{
17ee7397 179 errs *errp = s->errs;
87675353 180 size_t width = 0;
5092aba5
AD
181 int i;
182
8dd162d3 183 /* Compute the width of the look-ahead token column. */
d2576365
AD
184 for (i = 0; i < errp->num; ++i)
185 if (errp->symbols[i])
640748ee 186 max_length (&width, errp->symbols[i]->tag);
5092aba5 187
87675353
AD
188 /* Nothing to report. */
189 if (!width)
190 return;
e06f0c34 191
87675353
AD
192 fputc ('\n', out);
193 width += 2;
e06f0c34 194
8dd162d3 195 /* Report look-ahead tokens and errors. */
d2576365
AD
196 for (i = 0; i < errp->num; ++i)
197 if (errp->symbols[i])
87675353 198 {
640748ee 199 const char *tag = errp->symbols[i]->tag;
87675353
AD
200 int j;
201 fprintf (out, " %s", tag);
202 for (j = width - strlen (tag); j > 0; --j)
203 fputc (' ', out);
204 fputs (_("error (nonassociative)\n"), out);
205 }
e06f0c34
RS
206}
207
bc933ef1 208
17ee7397
PE
209/*-------------------------------------------------------------.
210| Return the default rule of S if it has one, NULL otherwise. |
211`-------------------------------------------------------------*/
bc933ef1 212
17ee7397
PE
213static rule *
214state_default_rule (state *s)
bc933ef1 215{
17ee7397
PE
216 reductions *reds = s->reductions;
217 rule *default_rule = NULL;
bc933ef1
AD
218 int cmax = 0;
219 int i;
220
8dd162d3 221 /* No need for a look-ahead. */
17ee7397
PE
222 if (s->consistent)
223 return reds->rules[0];
bc933ef1 224
8dd162d3 225 /* 1. Each reduction is possibly masked by the look-ahead tokens on which
bc933ef1 226 we shift (S/R conflicts)... */
8dd162d3 227 bitset_zero (shift_set);
bc933ef1 228 {
17ee7397
PE
229 transitions *trans = s->transitions;
230 FOR_EACH_SHIFT (trans, i)
640748ee
AD
231 {
232 /* If this state has a shift for the error token, don't use a
bc933ef1 233 default rule. */
17ee7397 234 if (TRANSITION_IS_ERROR (trans, i))
640748ee 235 return NULL;
8dd162d3 236 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
640748ee 237 }
bc933ef1
AD
238 }
239
8dd162d3 240 /* 2. Each reduction is possibly masked by the look-ahead tokens on which
bc933ef1
AD
241 we raise an error (due to %nonassoc). */
242 {
17ee7397 243 errs *errp = s->errs;
d2576365
AD
244 for (i = 0; i < errp->num; i++)
245 if (errp->symbols[i])
8dd162d3 246 bitset_set (shift_set, errp->symbols[i]->number);
bc933ef1
AD
247 }
248
17ee7397 249 for (i = 0; i < reds->num; ++i)
bc933ef1
AD
250 {
251 int count = 0;
252
8dd162d3
PE
253 /* How many non-masked look-ahead tokens are there for this
254 reduction? */
255 bitset_andn (look_ahead_set, reds->look_ahead_tokens[i], shift_set);
256 count = bitset_count (look_ahead_set);
bc933ef1
AD
257
258 if (count > cmax)
259 {
260 cmax = count;
17ee7397 261 default_rule = reds->rules[i];
bc933ef1
AD
262 }
263
264 /* 3. And finally, each reduction is possibly masked by previous
265 reductions (in R/R conflicts, we keep the first reductions).
266 */
8dd162d3 267 bitset_or (shift_set, shift_set, reds->look_ahead_tokens[i]);
bc933ef1
AD
268 }
269
270 return default_rule;
271}
272
273
8dd162d3
PE
274/*--------------------------------------------------------------------------.
275| Report a reduction of RULE on LOOK_AHEAD_TOKEN (which can be `default'). |
276| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
277| R/R conflicts). |
278`--------------------------------------------------------------------------*/
87675353
AD
279
280static void
281print_reduction (FILE *out, size_t width,
8dd162d3 282 const char *look_ahead_token,
17ee7397 283 rule *r, bool enabled)
87675353
AD
284{
285 int j;
8dd162d3
PE
286 fprintf (out, " %s", look_ahead_token);
287 for (j = width - strlen (look_ahead_token); j > 0; --j)
87675353
AD
288 fputc (' ', out);
289 if (!enabled)
290 fputc ('[', out);
17ee7397
PE
291 if (r->number)
292 fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
e8832397
AD
293 else
294 fprintf (out, _("accept"));
87675353
AD
295 if (!enabled)
296 fputc (']', out);
297 fputc ('\n', out);
298}
299
300
17ee7397
PE
301/*-------------------------------------------.
302| Report on OUT the reduction actions of S. |
303`-------------------------------------------*/
bc933ef1 304
5092aba5 305static void
17ee7397 306print_reductions (FILE *out, state *s)
5092aba5 307{
17ee7397
PE
308 transitions *trans = s->transitions;
309 reductions *reds = s->reductions;
310 rule *default_rule = NULL;
87675353
AD
311 size_t width = 0;
312 int i, j;
5092aba5 313
17ee7397 314 if (reds->num == 0)
80dac38c
AD
315 return;
316
17ee7397 317 default_rule = state_default_rule (s);
5092aba5 318
8dd162d3 319 bitset_zero (shift_set);
17ee7397 320 FOR_EACH_SHIFT (trans, i)
8dd162d3 321 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
5092aba5 322
8dd162d3 323 /* Compute the width of the look-ahead token column. */
87675353
AD
324 if (default_rule)
325 width = strlen (_("$default"));
cd08e51e 326
8dd162d3 327 if (reds->look_ahead_tokens)
cd08e51e
AD
328 for (i = 0; i < ntokens; i++)
329 {
8dd162d3 330 bool count = bitset_test (shift_set, i);
cd08e51e 331
17ee7397 332 for (j = 0; j < reds->num; ++j)
8dd162d3 333 if (bitset_test (reds->look_ahead_tokens[j], i))
cd08e51e 334 {
d0829076 335 if (! count)
cd08e51e 336 {
17ee7397 337 if (reds->rules[j] != default_rule)
cd08e51e 338 max_length (&width, symbols[i]->tag);
d0829076 339 count = true;
cd08e51e
AD
340 }
341 else
342 {
97650f4e 343 max_length (&width, symbols[i]->tag);
cd08e51e
AD
344 }
345 }
346 }
87675353
AD
347
348 /* Nothing to report. */
349 if (!width)
350 return;
351
352 fputc ('\n', out);
353 width += 2;
354
8dd162d3
PE
355 /* Report look-ahead tokens (or $default) and reductions. */
356 if (reds->look_ahead_tokens)
cd08e51e
AD
357 for (i = 0; i < ntokens; i++)
358 {
d0829076 359 bool defaulted = false;
8dd162d3 360 bool count = bitset_test (shift_set, i);
cd08e51e 361
17ee7397 362 for (j = 0; j < reds->num; ++j)
8dd162d3 363 if (bitset_test (reds->look_ahead_tokens[j], i))
cd08e51e 364 {
d0829076 365 if (! count)
cd08e51e 366 {
17ee7397 367 if (reds->rules[j] != default_rule)
cd08e51e
AD
368 print_reduction (out, width,
369 symbols[i]->tag,
17ee7397 370 reds->rules[j], true);
cd08e51e 371 else
d0829076
PE
372 defaulted = true;
373 count = true;
cd08e51e
AD
374 }
375 else
376 {
377 if (defaulted)
378 print_reduction (out, width,
379 symbols[i]->tag,
8307162d 380 default_rule, true);
d0829076 381 defaulted = false;
87675353 382 print_reduction (out, width,
97650f4e 383 symbols[i]->tag,
17ee7397 384 reds->rules[j], false);
cd08e51e
AD
385 }
386 }
387 }
bc933ef1
AD
388
389 if (default_rule)
87675353 390 print_reduction (out, width,
8307162d 391 _("$default"), default_rule, true);
5092aba5
AD
392}
393
394
bc933ef1
AD
395/*--------------------------------------------------------------.
396| Report on OUT all the actions (shifts, gotos, reductions, and |
17ee7397 397| explicit erros from %nonassoc) of S. |
bc933ef1
AD
398`--------------------------------------------------------------*/
399
5092aba5 400static void
17ee7397 401print_actions (FILE *out, state *s)
5092aba5 402{
87675353 403 /* Print shifts. */
17ee7397
PE
404 print_transitions (s, out, true);
405 print_errs (out, s);
406 print_reductions (out, s);
87675353 407 /* Print gotos. */
17ee7397 408 print_transitions (s, out, false);
5092aba5
AD
409}
410
bc933ef1 411
17ee7397
PE
412/*----------------------------------.
413| Report all the data on S on OUT. |
414`----------------------------------*/
87675353 415
07a58c13 416static void
17ee7397 417print_state (FILE *out, state *s)
07a58c13 418{
342b8b6e 419 fputs ("\n\n", out);
17ee7397 420 fprintf (out, _("state %d"), s->number);
87675353 421 fputc ('\n', out);
17ee7397
PE
422 print_core (out, s);
423 print_actions (out, s);
424 if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
7ea9a33f
AD
425 {
426 fputc ('\n', out);
17ee7397 427 fputs (s->solved_conflicts, out);
7ea9a33f 428 }
07a58c13
AD
429}
430\f
431/*-----------------------------------------.
432| Print information on the whole grammar. |
433`-----------------------------------------*/
434
342b8b6e
AD
435#define END_TEST(End) \
436do { \
437 if (column + strlen(buffer) > (End)) \
438 { \
439 fprintf (out, "%s\n ", buffer); \
440 column = 3; \
441 buffer[0] = 0; \
442 } \
ff4423cc 443} while (0)
e06f0c34 444
07a58c13 445
4a120d45 446static void
342b8b6e 447print_grammar (FILE *out)
e06f0c34 448{
17ee7397 449 symbol_number i;
e06f0c34
RS
450 char buffer[90];
451 int column = 0;
452
6b98e4b5 453 grammar_rules_print (out);
e06f0c34
RS
454
455 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 456 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 457 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 458 if (token_translations[i] != undeftoken->number)
342b8b6e 459 {
97650f4e 460 const char *tag = symbols[token_translations[i]]->tag;
17ee7397
PE
461 rule_number r;
462 item_number *rhsp;
9222837b 463
342b8b6e 464 buffer[0] = 0;
6b98e4b5
AD
465 column = strlen (tag);
466 fputs (tag, out);
342b8b6e
AD
467 END_TEST (50);
468 sprintf (buffer, " (%d)", i);
e06f0c34 469
4b3d3a8e 470 for (r = 0; r < nrules; r++)
9222837b
AD
471 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
472 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
473 {
474 END_TEST (65);
4b3d3a8e 475 sprintf (buffer + strlen (buffer), " %d", r);
342b8b6e
AD
476 break;
477 }
478 fprintf (out, "%s\n", buffer);
479 }
d2d1b42b
AD
480 fputs ("\n\n", out);
481
342b8b6e 482
d2d1b42b 483 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 484 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
485 {
486 int left_count = 0, right_count = 0;
17ee7397 487 rule_number r;
97650f4e 488 const char *tag = symbols[i]->tag;
e06f0c34 489
4b3d3a8e 490 for (r = 0; r < nrules; r++)
e06f0c34 491 {
17ee7397 492 item_number *rhsp;
6b98e4b5 493 if (rules[r].lhs->number == i)
e06f0c34 494 left_count++;
9222837b
AD
495 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
496 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
497 {
498 right_count++;
499 break;
500 }
501 }
502
503 buffer[0] = 0;
6b98e4b5
AD
504 fputs (tag, out);
505 column = strlen (tag);
e06f0c34
RS
506 sprintf (buffer, " (%d)", i);
507 END_TEST (0);
508
509 if (left_count > 0)
510 {
511 END_TEST (50);
c29240e7 512 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 513
4b3d3a8e 514 for (r = 0; r < nrules; r++)
e06f0c34
RS
515 {
516 END_TEST (65);
6b98e4b5 517 if (rules[r].lhs->number == i)
4b3d3a8e 518 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
519 }
520 }
521
522 if (right_count > 0)
523 {
524 if (left_count > 0)
c29240e7 525 sprintf (buffer + strlen (buffer), ",");
e06f0c34 526 END_TEST (50);
c29240e7 527 sprintf (buffer + strlen (buffer), _(" on right:"));
4b3d3a8e 528 for (r = 0; r < nrules; r++)
e06f0c34 529 {
17ee7397 530 item_number *rhsp;
9222837b
AD
531 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
532 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
533 {
534 END_TEST (65);
4b3d3a8e 535 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
536 break;
537 }
538 }
539 }
342b8b6e 540 fprintf (out, "%s\n", buffer);
e06f0c34
RS
541 }
542}
07a58c13
AD
543\f
544void
545print_results (void)
546{
17ee7397 547 state_number i;
07a58c13 548
64d15509
AD
549 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
550 that conflicts with Posix. */
551 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 552
64d15509 553 reduce_output (out);
c8f002c7
AD
554 grammar_rules_partial_print (out,
555 _("Rules never reduced"), rule_never_reduced_p);
64d15509 556 conflicts_output (out);
342b8b6e 557
64d15509 558 print_grammar (out);
342b8b6e 559
ec3bc396
AD
560 /* If the whole state item sets, not only the kernels, are wanted,
561 `closure' will be run, which needs memory allocation/deallocation. */
562 if (report_flag & report_itemsets)
9e7f6bbd 563 new_closure (nritems);
5092aba5 564 /* Storage for print_reductions. */
8dd162d3
PE
565 shift_set = bitset_create (ntokens, BITSET_FIXED);
566 look_ahead_set = bitset_create (ntokens, BITSET_FIXED);
64d15509 567 for (i = 0; i < nstates; i++)
29e88316 568 print_state (out, states[i]);
8dd162d3
PE
569 bitset_free (shift_set);
570 bitset_free (look_ahead_set);
ec3bc396 571 if (report_flag & report_itemsets)
64d15509
AD
572 free_closure ();
573
574 xfclose (out);
07a58c13 575}