]> git.saurik.com Git - bison.git/blame - src/print.c
maint: prepare to use date ranges in copyright notices.
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
a737b216 2
6e30ede8
PE
3 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005,
4 2007, 2009, 2010 Free 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>
25#include <quotearg.h>
26
b2ca4022 27#include "LR0.h"
17ee7397 28#include "closure.h"
0619caf0 29#include "conflicts.h"
17ee7397 30#include "files.h"
07a58c13 31#include "getargs.h"
17ee7397
PE
32#include "gram.h"
33#include "lalr.h"
23ec25b7 34#include "muscle-tab.h"
d7913476 35#include "print.h"
17ee7397 36#include "reader.h"
09b503c8 37#include "reduce.h"
17ee7397
PE
38#include "state.h"
39#include "symtab.h"
0bf92491 40#include "tables.h"
e06f0c34 41
9d774aff 42static bitset no_reduce_set;
5092aba5 43
07a58c13 44#if 0
4a120d45 45static void
d2729d44 46print_token (int extnum, int token)
e06f0c34 47{
342b8b6e 48 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 49}
4a120d45 50#endif
e06f0c34 51
07a58c13 52\f
87675353
AD
53
54/*---------------------------------------.
55| *WIDTH := max (*WIDTH, strlen (STR)). |
56`---------------------------------------*/
57
58static void
59max_length (size_t *width, const char *str)
60{
61 size_t len = strlen (str);
62 if (len > *width)
63 *width = len;
64}
65
342b8b6e 66/*--------------------------------.
07a58c13 67| Report information on a state. |
342b8b6e 68`--------------------------------*/
e06f0c34 69
4a120d45 70static void
17ee7397 71print_core (FILE *out, state *s)
e06f0c34 72{
f6fbd3da 73 size_t i;
17ee7397 74 item_number *sitems = s->items;
f6fbd3da 75 size_t snritems = s->nitems;
17ee7397 76 symbol *previous_lhs = NULL;
e06f0c34 77
ec3bc396
AD
78 /* Output all the items of a state, not only its kernel. */
79 if (report_flag & report_itemsets)
43168960 80 {
5123689b 81 closure (sitems, snritems);
43168960 82 sitems = itemset;
b09f4f48 83 snritems = nitemset;
43168960 84 }
e06f0c34 85
ce4ccb4b
AD
86 if (!snritems)
87 return;
e06f0c34 88
87675353
AD
89 fputc ('\n', out);
90
ce4ccb4b
AD
91 for (i = 0; i < snritems; i++)
92 {
17ee7397
PE
93 item_number *sp;
94 item_number *sp1;
a737b216 95 rule_number r;
e06f0c34 96
ce4ccb4b 97 sp1 = sp = ritem + sitems[i];
e06f0c34 98
ce4ccb4b
AD
99 while (*sp >= 0)
100 sp++;
e06f0c34 101
17ee7397 102 r = item_number_as_rule_number (*sp);
e06f0c34 103
17ee7397
PE
104 rule_lhs_print (&rules[r], previous_lhs, out);
105 previous_lhs = rules[r].lhs;
43168960 106
17ee7397 107 for (sp = rules[r].rhs; sp < sp1; sp++)
97650f4e 108 fprintf (out, " %s", symbols[*sp]->tag);
ce4ccb4b
AD
109 fputs (" .", out);
110 for (/* Nothing */; *sp >= 0; ++sp)
97650f4e 111 fprintf (out, " %s", symbols[*sp]->tag);
d4e7d3a1 112
742e4900 113 /* Display the lookahead tokens? */
a0de5091
JD
114 if (report_flag & report_lookahead_tokens
115 && item_number_is_rule_number (*sp1))
742e4900 116 state_rule_lookahead_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
742e4900 135 /* Compute the width of the lookahead 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
742e4900 151 /* Report lookahead 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
742e4900 183 /* Compute the width of the lookahead 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
742e4900 195 /* Report lookahead 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
742e4900
JD
209/*-------------------------------------------------------------------------.
210| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
211| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
212| R/R conflicts). |
213`-------------------------------------------------------------------------*/
87675353
AD
214
215static void
216print_reduction (FILE *out, size_t width,
742e4900 217 const char *lookahead_token,
17ee7397 218 rule *r, bool enabled)
87675353
AD
219{
220 int j;
742e4900
JD
221 fprintf (out, " %s", lookahead_token);
222 for (j = width - strlen (lookahead_token); j > 0; --j)
87675353
AD
223 fputc (' ', out);
224 if (!enabled)
225 fputc ('[', out);
17ee7397
PE
226 if (r->number)
227 fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
e8832397
AD
228 else
229 fprintf (out, _("accept"));
87675353
AD
230 if (!enabled)
231 fputc (']', out);
232 fputc ('\n', out);
233}
234
235
17ee7397
PE
236/*-------------------------------------------.
237| Report on OUT the reduction actions of S. |
238`-------------------------------------------*/
bc933ef1 239
5092aba5 240static void
17ee7397 241print_reductions (FILE *out, state *s)
5092aba5 242{
17ee7397
PE
243 transitions *trans = s->transitions;
244 reductions *reds = s->reductions;
620b5727 245 rule *default_reduction = NULL;
87675353
AD
246 size_t width = 0;
247 int i, j;
379261b3 248 bool default_reduction_only = true;
5092aba5 249
17ee7397 250 if (reds->num == 0)
80dac38c
AD
251 return;
252
0bf92491 253 if (yydefact[s->number] != 0)
620b5727 254 default_reduction = &rules[yydefact[s->number] - 1];
5092aba5 255
9d774aff 256 bitset_zero (no_reduce_set);
17ee7397 257 FOR_EACH_SHIFT (trans, i)
9d774aff
JD
258 bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
259 for (i = 0; i < s->errs->num; ++i)
260 if (s->errs->symbols[i])
261 bitset_set (no_reduce_set, s->errs->symbols[i]->number);
5092aba5 262
742e4900 263 /* Compute the width of the lookahead token column. */
620b5727 264 if (default_reduction)
87675353 265 width = strlen (_("$default"));
cd08e51e 266
742e4900 267 if (reds->lookahead_tokens)
cd08e51e
AD
268 for (i = 0; i < ntokens; i++)
269 {
9d774aff 270 bool count = bitset_test (no_reduce_set, i);
cd08e51e 271
17ee7397 272 for (j = 0; j < reds->num; ++j)
742e4900 273 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 274 {
d0829076 275 if (! count)
cd08e51e 276 {
620b5727 277 if (reds->rules[j] != default_reduction)
cd08e51e 278 max_length (&width, symbols[i]->tag);
d0829076 279 count = true;
cd08e51e
AD
280 }
281 else
282 {
97650f4e 283 max_length (&width, symbols[i]->tag);
cd08e51e
AD
284 }
285 }
286 }
87675353
AD
287
288 /* Nothing to report. */
289 if (!width)
290 return;
291
292 fputc ('\n', out);
293 width += 2;
294
742e4900
JD
295 /* Report lookahead tokens (or $default) and reductions. */
296 if (reds->lookahead_tokens)
cd08e51e
AD
297 for (i = 0; i < ntokens; i++)
298 {
d0829076 299 bool defaulted = false;
9d774aff 300 bool count = bitset_test (no_reduce_set, i);
03c07b03 301 if (count)
379261b3 302 default_reduction_only = false;
cd08e51e 303
17ee7397 304 for (j = 0; j < reds->num; ++j)
742e4900 305 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 306 {
d0829076 307 if (! count)
cd08e51e 308 {
620b5727 309 if (reds->rules[j] != default_reduction)
03c07b03 310 {
379261b3 311 default_reduction_only = false;
03c07b03
JD
312 print_reduction (out, width,
313 symbols[i]->tag,
314 reds->rules[j], true);
315 }
cd08e51e 316 else
d0829076
PE
317 defaulted = true;
318 count = true;
cd08e51e
AD
319 }
320 else
321 {
379261b3 322 default_reduction_only = false;
cd08e51e
AD
323 if (defaulted)
324 print_reduction (out, width,
325 symbols[i]->tag,
620b5727 326 default_reduction, true);
d0829076 327 defaulted = false;
87675353 328 print_reduction (out, width,
97650f4e 329 symbols[i]->tag,
17ee7397 330 reds->rules[j], false);
cd08e51e
AD
331 }
332 }
333 }
bc933ef1 334
620b5727 335 if (default_reduction)
03c07b03 336 {
620b5727 337 char *default_reductions =
1d0f55cc 338 muscle_percent_define_get ("lr.default-reductions");
620b5727
JD
339 print_reduction (out, width, _("$default"), default_reduction, true);
340 aver (0 == strcmp (default_reductions, "all")
341 || (0 == strcmp (default_reductions, "consistent")
379261b3 342 && default_reduction_only)
03c07b03 343 || (reds->num == 1 && reds->rules[0]->number == 0));
620b5727 344 free (default_reductions);
03c07b03 345 }
5092aba5
AD
346}
347
348
bc933ef1
AD
349/*--------------------------------------------------------------.
350| Report on OUT all the actions (shifts, gotos, reductions, and |
17ee7397 351| explicit erros from %nonassoc) of S. |
bc933ef1
AD
352`--------------------------------------------------------------*/
353
5092aba5 354static void
17ee7397 355print_actions (FILE *out, state *s)
5092aba5 356{
87675353 357 /* Print shifts. */
17ee7397
PE
358 print_transitions (s, out, true);
359 print_errs (out, s);
360 print_reductions (out, s);
87675353 361 /* Print gotos. */
17ee7397 362 print_transitions (s, out, false);
5092aba5
AD
363}
364
bc933ef1 365
17ee7397
PE
366/*----------------------------------.
367| Report all the data on S on OUT. |
368`----------------------------------*/
87675353 369
07a58c13 370static void
17ee7397 371print_state (FILE *out, state *s)
07a58c13 372{
342b8b6e 373 fputs ("\n\n", out);
17ee7397 374 fprintf (out, _("state %d"), s->number);
87675353 375 fputc ('\n', out);
17ee7397
PE
376 print_core (out, s);
377 print_actions (out, s);
378 if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
7ea9a33f
AD
379 {
380 fputc ('\n', out);
17ee7397 381 fputs (s->solved_conflicts, out);
7ea9a33f 382 }
07a58c13
AD
383}
384\f
385/*-----------------------------------------.
386| Print information on the whole grammar. |
387`-----------------------------------------*/
388
342b8b6e
AD
389#define END_TEST(End) \
390do { \
391 if (column + strlen(buffer) > (End)) \
392 { \
393 fprintf (out, "%s\n ", buffer); \
394 column = 3; \
395 buffer[0] = 0; \
396 } \
ff4423cc 397} while (0)
e06f0c34 398
07a58c13 399
4a120d45 400static void
342b8b6e 401print_grammar (FILE *out)
e06f0c34 402{
17ee7397 403 symbol_number i;
e06f0c34
RS
404 char buffer[90];
405 int column = 0;
406
6b98e4b5 407 grammar_rules_print (out);
e06f0c34
RS
408
409 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 410 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 411 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 412 if (token_translations[i] != undeftoken->number)
342b8b6e 413 {
97650f4e 414 const char *tag = symbols[token_translations[i]]->tag;
17ee7397
PE
415 rule_number r;
416 item_number *rhsp;
9222837b 417
342b8b6e 418 buffer[0] = 0;
6b98e4b5
AD
419 column = strlen (tag);
420 fputs (tag, out);
21f1b063 421 END_TEST (65);
342b8b6e 422 sprintf (buffer, " (%d)", i);
e06f0c34 423
4b3d3a8e 424 for (r = 0; r < nrules; r++)
9222837b
AD
425 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
426 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
427 {
428 END_TEST (65);
4b3d3a8e 429 sprintf (buffer + strlen (buffer), " %d", r);
342b8b6e
AD
430 break;
431 }
432 fprintf (out, "%s\n", buffer);
433 }
d2d1b42b
AD
434 fputs ("\n\n", out);
435
342b8b6e 436
d2d1b42b 437 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 438 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
439 {
440 int left_count = 0, right_count = 0;
17ee7397 441 rule_number r;
97650f4e 442 const char *tag = symbols[i]->tag;
e06f0c34 443
4b3d3a8e 444 for (r = 0; r < nrules; r++)
e06f0c34 445 {
17ee7397 446 item_number *rhsp;
6b98e4b5 447 if (rules[r].lhs->number == i)
e06f0c34 448 left_count++;
9222837b
AD
449 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
450 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
451 {
452 right_count++;
453 break;
454 }
455 }
456
457 buffer[0] = 0;
6b98e4b5
AD
458 fputs (tag, out);
459 column = strlen (tag);
e06f0c34
RS
460 sprintf (buffer, " (%d)", i);
461 END_TEST (0);
462
463 if (left_count > 0)
464 {
21f1b063 465 END_TEST (65);
c29240e7 466 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 467
4b3d3a8e 468 for (r = 0; r < nrules; r++)
e06f0c34 469 {
6b98e4b5 470 if (rules[r].lhs->number == i)
21f1b063
JD
471 {
472 END_TEST (65);
473 sprintf (buffer + strlen (buffer), " %d", r);
474 }
e06f0c34
RS
475 }
476 }
477
478 if (right_count > 0)
479 {
480 if (left_count > 0)
c29240e7 481 sprintf (buffer + strlen (buffer), ",");
21f1b063 482 END_TEST (65);
c29240e7 483 sprintf (buffer + strlen (buffer), _(" on right:"));
4b3d3a8e 484 for (r = 0; r < nrules; r++)
e06f0c34 485 {
17ee7397 486 item_number *rhsp;
9222837b
AD
487 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
488 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
489 {
490 END_TEST (65);
4b3d3a8e 491 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
492 break;
493 }
494 }
495 }
342b8b6e 496 fprintf (out, "%s\n", buffer);
e06f0c34
RS
497 }
498}
07a58c13
AD
499\f
500void
501print_results (void)
502{
17ee7397 503 state_number i;
07a58c13 504
64d15509
AD
505 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
506 that conflicts with Posix. */
507 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 508
64d15509 509 reduce_output (out);
c8f002c7 510 grammar_rules_partial_print (out,
cff03fb2
JD
511 _("Rules useless in parser due to conflicts"),
512 rule_useless_in_parser_p);
64d15509 513 conflicts_output (out);
342b8b6e 514
64d15509 515 print_grammar (out);
342b8b6e 516
ec3bc396
AD
517 /* If the whole state item sets, not only the kernels, are wanted,
518 `closure' will be run, which needs memory allocation/deallocation. */
519 if (report_flag & report_itemsets)
9e7f6bbd 520 new_closure (nritems);
5092aba5 521 /* Storage for print_reductions. */
9d774aff 522 no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
64d15509 523 for (i = 0; i < nstates; i++)
29e88316 524 print_state (out, states[i]);
9d774aff 525 bitset_free (no_reduce_set);
ec3bc396 526 if (report_flag & report_itemsets)
64d15509
AD
527 free_closure ();
528
529 xfclose (out);
07a58c13 530}