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