]> git.saurik.com Git - bison.git/blame - src/print.c
Use C99-style bool instead of our own style.
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
b0299a2e
AD
2 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002
3 Free Software Foundation, Inc.
e06f0c34 4
c29240e7 5 This file is part of Bison, the GNU Compiler Compiler.
e06f0c34 6
c29240e7
AD
7 Bison is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
e06f0c34 11
c29240e7
AD
12 Bison is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
e06f0c34 16
c29240e7
AD
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
e06f0c34
RS
21
22
e06f0c34 23#include "system.h"
8adfa272 24#include "quotearg.h"
e06f0c34 25#include "files.h"
ad949da9 26#include "symtab.h"
e06f0c34 27#include "gram.h"
b2ca4022 28#include "LR0.h"
720d742f 29#include "lalr.h"
0619caf0 30#include "conflicts.h"
07a58c13
AD
31#include "getargs.h"
32#include "state.h"
b2ca4022 33#include "reader.h"
d7913476 34#include "print.h"
09b503c8 35#include "reduce.h"
43168960 36#include "closure.h"
34ba9743 37#include "bitset.h"
e06f0c34 38
34ba9743
AD
39static bitset shiftset;
40static bitset lookaheadset;
5092aba5 41
07a58c13 42#if 0
4a120d45 43static void
d2729d44 44print_token (int extnum, int token)
e06f0c34 45{
342b8b6e 46 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 47}
4a120d45 48#endif
e06f0c34 49
07a58c13 50\f
87675353
AD
51
52/*---------------------------------------.
53| *WIDTH := max (*WIDTH, strlen (STR)). |
54`---------------------------------------*/
55
56static void
57max_length (size_t *width, const char *str)
58{
59 size_t len = strlen (str);
60 if (len > *width)
61 *width = len;
62}
63
342b8b6e 64/*--------------------------------.
07a58c13 65| Report information on a state. |
342b8b6e 66`--------------------------------*/
e06f0c34 67
4a120d45 68static void
065fbd27 69print_core (FILE *out, state_t *state)
e06f0c34 70{
c29240e7 71 int i;
62a3e4f0 72 item_number_t *sitems = state->items;
5123689b 73 int snritems = state->nitems;
ce4ccb4b 74 symbol_t *previous_lhs = NULL;
e06f0c34 75
ec3bc396
AD
76 /* Output all the items of a state, not only its kernel. */
77 if (report_flag & report_itemsets)
43168960 78 {
5123689b 79 closure (sitems, snritems);
43168960 80 sitems = itemset;
5123689b 81 snritems = nritemset;
43168960 82 }
e06f0c34 83
ce4ccb4b
AD
84 if (!snritems)
85 return;
e06f0c34 86
87675353
AD
87 fputc ('\n', out);
88
ce4ccb4b
AD
89 for (i = 0; i < snritems; i++)
90 {
91 item_number_t *sp;
92 item_number_t *sp1;
93 int rule;
e06f0c34 94
ce4ccb4b 95 sp1 = sp = ritem + sitems[i];
e06f0c34 96
ce4ccb4b
AD
97 while (*sp >= 0)
98 sp++;
e06f0c34 99
4b3d3a8e 100 rule = item_number_as_rule_number (*sp);
e06f0c34 101
ce4ccb4b
AD
102 rule_lhs_print (&rules[rule], previous_lhs, out);
103 previous_lhs = rules[rule].lhs;
43168960 104
ce4ccb4b 105 for (sp = rules[rule].rhs; sp < sp1; sp++)
97650f4e 106 fprintf (out, " %s", symbols[*sp]->tag);
ce4ccb4b
AD
107 fputs (" .", out);
108 for (/* Nothing */; *sp >= 0; ++sp)
97650f4e 109 fprintf (out, " %s", symbols[*sp]->tag);
d4e7d3a1 110
ce4ccb4b
AD
111 /* Display the lookaheads? */
112 if (report_flag & report_lookaheads)
113 state_rule_lookaheads_print (state, &rules[rule], out);
e06f0c34 114
342b8b6e 115 fputc ('\n', out);
e06f0c34 116 }
e06f0c34
RS
117}
118
5092aba5 119
87675353
AD
120/*----------------------------------------------------------------.
121| Report the shifts iff DISPLAY_SHIFTS_P or the gotos of STATE on |
122| OUT. |
123`----------------------------------------------------------------*/
124
4a120d45 125static void
ccaf65bc 126print_transitions (state_t *state, FILE *out, bool display_transitions_p)
e06f0c34 127{
8b752b00 128 transitions_t *transitions = state->transitions;
87675353
AD
129 size_t width = 0;
130 int i;
e06f0c34 131
87675353 132 /* Compute the width of the lookaheads column. */
ccaf65bc
AD
133 for (i = 0; i < transitions->num; i++)
134 if (!TRANSITION_IS_DISABLED (transitions, i)
135 && TRANSITION_IS_SHIFT (transitions, i) == display_transitions_p)
d954473d 136 {
ccaf65bc 137 symbol_t *symbol = symbols[TRANSITION_SYMBOL (transitions, i)];
97650f4e 138 max_length (&width, symbol->tag);
d954473d 139 }
e06f0c34 140
87675353
AD
141 /* Nothing to report. */
142 if (!width)
143 return;
144
145 fputc ('\n', out);
146 width += 2;
147
148 /* Report lookaheads and shifts. */
ccaf65bc
AD
149 for (i = 0; i < transitions->num; i++)
150 if (!TRANSITION_IS_DISABLED (transitions, i)
151 && TRANSITION_IS_SHIFT (transitions, i) == display_transitions_p)
87675353 152 {
ccaf65bc 153 symbol_t *symbol = symbols[TRANSITION_SYMBOL (transitions, i)];
97650f4e 154 const char *tag = symbol->tag;
640748ee 155 state_t *state1 = transitions->states[i];
87675353
AD
156 int j;
157
158 fprintf (out, " %s", tag);
159 for (j = width - strlen (tag); j > 0; --j)
160 fputc (' ', out);
ccaf65bc 161 if (display_transitions_p)
640748ee 162 fprintf (out, _("shift, and go to state %d\n"), state1->number);
87675353 163 else
640748ee 164 fprintf (out, _("go to state %d\n"), state1->number);
87675353 165 }
5092aba5 166}
e06f0c34 167
e06f0c34 168
87675353
AD
169/*------------------------------------------------------------.
170| Report the explicit errors of STATE raised from %nonassoc. |
171`------------------------------------------------------------*/
172
5092aba5
AD
173static void
174print_errs (FILE *out, state_t *state)
175{
8a731ca8 176 errs_t *errp = state->errs;
87675353 177 size_t width = 0;
5092aba5
AD
178 int i;
179
87675353 180 /* Compute the width of the lookaheads column. */
d2576365
AD
181 for (i = 0; i < errp->num; ++i)
182 if (errp->symbols[i])
640748ee 183 max_length (&width, errp->symbols[i]->tag);
5092aba5 184
87675353
AD
185 /* Nothing to report. */
186 if (!width)
187 return;
e06f0c34 188
87675353
AD
189 fputc ('\n', out);
190 width += 2;
e06f0c34 191
87675353 192 /* Report lookaheads and errors. */
d2576365
AD
193 for (i = 0; i < errp->num; ++i)
194 if (errp->symbols[i])
87675353 195 {
640748ee 196 const char *tag = errp->symbols[i]->tag;
87675353
AD
197 int j;
198 fprintf (out, " %s", tag);
199 for (j = width - strlen (tag); j > 0; --j)
200 fputc (' ', out);
201 fputs (_("error (nonassociative)\n"), out);
202 }
e06f0c34
RS
203}
204
bc933ef1
AD
205
206/*----------------------------------------------------------.
207| Return the default rule of this STATE if it has one, NULL |
208| otherwise. |
209`----------------------------------------------------------*/
210
211static rule_t *
87675353 212state_default_rule (state_t *state)
bc933ef1
AD
213{
214 reductions_t *redp = state->reductions;
215 rule_t *default_rule = NULL;
216 int cmax = 0;
217 int i;
218
219 /* No need for a lookahead. */
220 if (state->consistent)
640748ee 221 return redp->rules[0];
bc933ef1
AD
222
223 /* 1. Each reduction is possibly masked by the lookaheads on which
224 we shift (S/R conflicts)... */
225 bitset_zero (shiftset);
226 {
8b752b00 227 transitions_t *transitions = state->transitions;
640748ee
AD
228 FOR_EACH_SHIFT (transitions, i)
229 {
230 /* If this state has a shift for the error token, don't use a
bc933ef1 231 default rule. */
640748ee
AD
232 if (TRANSITION_IS_ERROR (transitions, i))
233 return NULL;
234 bitset_set (shiftset, TRANSITION_SYMBOL (transitions, i));
235 }
bc933ef1
AD
236 }
237
238 /* 2. Each reduction is possibly masked by the lookaheads on which
239 we raise an error (due to %nonassoc). */
240 {
241 errs_t *errp = state->errs;
d2576365
AD
242 for (i = 0; i < errp->num; i++)
243 if (errp->symbols[i])
640748ee 244 bitset_set (shiftset, errp->symbols[i]->number);
bc933ef1
AD
245 }
246
cd08e51e 247 for (i = 0; i < redp->num; ++i)
bc933ef1
AD
248 {
249 int count = 0;
250
251 /* How many non-masked lookaheads are there for this reduction?
252 */
cd08e51e 253 bitset_andn (lookaheadset, redp->lookaheads[i], shiftset);
bc933ef1
AD
254 count = bitset_count (lookaheadset);
255
256 if (count > cmax)
257 {
258 cmax = count;
cd08e51e 259 default_rule = redp->rules[i];
bc933ef1
AD
260 }
261
262 /* 3. And finally, each reduction is possibly masked by previous
263 reductions (in R/R conflicts, we keep the first reductions).
264 */
cd08e51e 265 bitset_or (shiftset, shiftset, redp->lookaheads[i]);
bc933ef1
AD
266 }
267
268 return default_rule;
269}
270
271
87675353
AD
272/*--------------------------------------------------------------------.
273| Report a reduction of RULE on LOOKAHEADS (which can be `default'). |
274| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
275| R/R conflicts). |
276`--------------------------------------------------------------------*/
277
278static void
279print_reduction (FILE *out, size_t width,
280 const char *lookahead,
281 rule_t *rule, bool enabled)
282{
283 int j;
284 fprintf (out, " %s", lookahead);
285 for (j = width - strlen (lookahead); j > 0; --j)
286 fputc (' ', out);
287 if (!enabled)
288 fputc ('[', out);
e8832397
AD
289 if (rule->number)
290 fprintf (out, _("reduce using rule %d (%s)"),
291 rule->number, rule->lhs->tag);
292 else
293 fprintf (out, _("accept"));
87675353
AD
294 if (!enabled)
295 fputc (']', out);
296 fputc ('\n', out);
297}
298
299
bc933ef1
AD
300/*----------------------------------------------------.
301| Report on OUT the reduction actions of this STATE. |
302`----------------------------------------------------*/
303
5092aba5
AD
304static void
305print_reductions (FILE *out, state_t *state)
306{
8b752b00 307 transitions_t *transitions = state->transitions;
8a731ca8 308 reductions_t *redp = state->reductions;
bc933ef1 309 rule_t *default_rule = NULL;
87675353
AD
310 size_t width = 0;
311 int i, j;
5092aba5 312
d2576365 313 if (redp->num == 0)
80dac38c
AD
314 return;
315
87675353 316 default_rule = state_default_rule (state);
5092aba5 317
34ba9743 318 bitset_zero (shiftset);
640748ee
AD
319 FOR_EACH_SHIFT (transitions, i)
320 bitset_set (shiftset, TRANSITION_SYMBOL (transitions, i));
5092aba5 321
87675353
AD
322 /* Compute the width of the lookaheads column. */
323 if (default_rule)
324 width = strlen (_("$default"));
cd08e51e
AD
325
326 if (redp->lookaheads)
327 for (i = 0; i < ntokens; i++)
328 {
329 int count = bitset_test (shiftset, i);
330
331 for (j = 0; j < redp->num; ++j)
332 if (bitset_test (redp->lookaheads[j], i))
333 {
334 if (count == 0)
335 {
336 if (redp->rules[j] != default_rule)
337 max_length (&width, symbols[i]->tag);
338 count++;
339 }
340 else
341 {
97650f4e 342 max_length (&width, symbols[i]->tag);
cd08e51e
AD
343 }
344 }
345 }
87675353
AD
346
347 /* Nothing to report. */
348 if (!width)
349 return;
350
351 fputc ('\n', out);
352 width += 2;
353
354 /* Report lookaheads (or $default) and reductions. */
cd08e51e
AD
355 if (redp->lookaheads)
356 for (i = 0; i < ntokens; i++)
357 {
358 int defaulted = 0;
359 int count = bitset_test (shiftset, i);
360
361 for (j = 0; j < redp->num; ++j)
362 if (bitset_test (redp->lookaheads[j], i))
363 {
364 if (count == 0)
365 {
366 if (redp->rules[j] != default_rule)
367 print_reduction (out, width,
368 symbols[i]->tag,
369 redp->rules[j], TRUE);
370 else
371 defaulted = 1;
372 count++;
373 }
374 else
375 {
376 if (defaulted)
377 print_reduction (out, width,
378 symbols[i]->tag,
379 default_rule, TRUE);
380 defaulted = 0;
87675353 381 print_reduction (out, width,
97650f4e 382 symbols[i]->tag,
cd08e51e
AD
383 redp->rules[j], FALSE);
384 }
385 }
386 }
bc933ef1
AD
387
388 if (default_rule)
87675353
AD
389 print_reduction (out, width,
390 _("$default"), default_rule, TRUE);
5092aba5
AD
391}
392
393
bc933ef1
AD
394/*--------------------------------------------------------------.
395| Report on OUT all the actions (shifts, gotos, reductions, and |
396| explicit erros from %nonassoc) of STATE. |
397`--------------------------------------------------------------*/
398
5092aba5
AD
399static void
400print_actions (FILE *out, state_t *state)
401{
87675353
AD
402 /* Print shifts. */
403 print_transitions (state, out, TRUE);
5092aba5 404 print_errs (out, state);
80dac38c 405 print_reductions (out, state);
87675353
AD
406 /* Print gotos. */
407 print_transitions (state, out, FALSE);
5092aba5
AD
408}
409
bc933ef1 410
87675353
AD
411/*--------------------------------------.
412| Report all the data on STATE on OUT. |
413`--------------------------------------*/
414
07a58c13 415static void
065fbd27 416print_state (FILE *out, state_t *state)
07a58c13 417{
342b8b6e 418 fputs ("\n\n", out);
87675353
AD
419 fprintf (out, _("state %d"), state->number);
420 fputc ('\n', out);
342b8b6e
AD
421 print_core (out, state);
422 print_actions (out, state);
b408954b
AD
423 if ((report_flag & report_solved_conflicts)
424 && state->solved_conflicts)
7ea9a33f
AD
425 {
426 fputc ('\n', out);
427 fputs (state->solved_conflicts, out);
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{
a49aecd5 449 symbol_number_t 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;
9222837b
AD
461 rule_number_t r;
462 item_number_t *rhsp;
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;
9222837b 487 rule_number_t r;
97650f4e 488 const char *tag = symbols[i]->tag;
e06f0c34 489
4b3d3a8e 490 for (r = 0; r < nrules; r++)
e06f0c34 491 {
9222837b 492 item_number_t *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 {
9222837b
AD
530 item_number_t *rhsp;
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{
d57650a5 547 state_number_t 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. */
34ba9743 565 shiftset = bitset_create (ntokens, BITSET_FIXED);
34ba9743 566 lookaheadset = bitset_create (ntokens, BITSET_FIXED);
64d15509 567 for (i = 0; i < nstates; i++)
29e88316 568 print_state (out, states[i]);
34ba9743
AD
569 bitset_free (shiftset);
570 bitset_free (lookaheadset);
ec3bc396 571 if (report_flag & report_itemsets)
64d15509
AD
572 free_closure ();
573
574 xfclose (out);
07a58c13 575}