]> git.saurik.com Git - bison.git/blame - src/print.c
doc: improve html and pdf rendering
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
a737b216 2
3209eb1c 3 Copyright (C) 1984, 1986, 1989, 2000-2005, 2007, 2009-2015 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 108 fputs (" .", out);
21cf8039
AD
109 if (0 <= *rules[r].rhs)
110 for (/* Nothing */; 0 <= *sp; ++sp)
111 fprintf (out, " %s", symbols[*sp]->tag);
112 else
113 fprintf (out, " %%empty");
d4e7d3a1 114
742e4900 115 /* Display the lookahead tokens? */
a0de5091
JD
116 if (report_flag & report_lookahead_tokens
117 && item_number_is_rule_number (*sp1))
e9690142 118 state_rule_lookahead_tokens_print (s, &rules[r], out);
e06f0c34 119
342b8b6e 120 fputc ('\n', out);
e06f0c34 121 }
e06f0c34
RS
122}
123
5092aba5 124
17ee7397
PE
125/*------------------------------------------------------------.
126| Report the shifts iff DISPLAY_SHIFTS_P or the gotos of S on |
127| OUT. |
128`------------------------------------------------------------*/
87675353 129
4a120d45 130static void
17ee7397 131print_transitions (state *s, FILE *out, bool display_transitions_p)
e06f0c34 132{
17ee7397 133 transitions *trans = s->transitions;
87675353
AD
134 size_t width = 0;
135 int i;
e06f0c34 136
742e4900 137 /* Compute the width of the lookahead token column. */
17ee7397
PE
138 for (i = 0; i < trans->num; i++)
139 if (!TRANSITION_IS_DISABLED (trans, i)
e9690142 140 && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
d954473d 141 {
e9690142
JD
142 symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
143 max_length (&width, sym->tag);
d954473d 144 }
e06f0c34 145
87675353
AD
146 /* Nothing to report. */
147 if (!width)
148 return;
149
150 fputc ('\n', out);
151 width += 2;
152
742e4900 153 /* Report lookahead tokens and shifts. */
17ee7397
PE
154 for (i = 0; i < trans->num; i++)
155 if (!TRANSITION_IS_DISABLED (trans, i)
e9690142 156 && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
87675353 157 {
e9690142
JD
158 symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
159 const char *tag = sym->tag;
160 state *s1 = trans->states[i];
161 int j;
162
163 fprintf (out, " %s", tag);
164 for (j = width - strlen (tag); j > 0; --j)
165 fputc (' ', out);
166 if (display_transitions_p)
167 fprintf (out, _("shift, and go to state %d\n"), s1->number);
168 else
169 fprintf (out, _("go to state %d\n"), s1->number);
87675353 170 }
5092aba5 171}
e06f0c34 172
e06f0c34 173
17ee7397
PE
174/*--------------------------------------------------------.
175| Report the explicit errors of S raised from %nonassoc. |
176`--------------------------------------------------------*/
87675353 177
5092aba5 178static void
17ee7397 179print_errs (FILE *out, state *s)
5092aba5 180{
17ee7397 181 errs *errp = s->errs;
87675353 182 size_t width = 0;
5092aba5
AD
183 int i;
184
742e4900 185 /* Compute the width of the lookahead token column. */
d2576365
AD
186 for (i = 0; i < errp->num; ++i)
187 if (errp->symbols[i])
640748ee 188 max_length (&width, errp->symbols[i]->tag);
5092aba5 189
87675353
AD
190 /* Nothing to report. */
191 if (!width)
192 return;
e06f0c34 193
87675353
AD
194 fputc ('\n', out);
195 width += 2;
e06f0c34 196
742e4900 197 /* Report lookahead tokens and errors. */
d2576365
AD
198 for (i = 0; i < errp->num; ++i)
199 if (errp->symbols[i])
87675353 200 {
e9690142
JD
201 const char *tag = errp->symbols[i]->tag;
202 int j;
203 fprintf (out, " %s", tag);
204 for (j = width - strlen (tag); j > 0; --j)
205 fputc (' ', out);
206 fputs (_("error (nonassociative)\n"), out);
87675353 207 }
e06f0c34
RS
208}
209
bc933ef1 210
742e4900 211/*-------------------------------------------------------------------------.
45eebca4 212| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
742e4900
JD
213| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
214| R/R conflicts). |
215`-------------------------------------------------------------------------*/
87675353
AD
216
217static void
218print_reduction (FILE *out, size_t width,
e9690142
JD
219 const char *lookahead_token,
220 rule *r, bool enabled)
87675353
AD
221{
222 int j;
742e4900
JD
223 fprintf (out, " %s", lookahead_token);
224 for (j = width - strlen (lookahead_token); j > 0; --j)
87675353
AD
225 fputc (' ', out);
226 if (!enabled)
227 fputc ('[', out);
17ee7397
PE
228 if (r->number)
229 fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
e8832397
AD
230 else
231 fprintf (out, _("accept"));
87675353
AD
232 if (!enabled)
233 fputc (']', out);
234 fputc ('\n', out);
235}
236
237
17ee7397
PE
238/*-------------------------------------------.
239| Report on OUT the reduction actions of S. |
240`-------------------------------------------*/
bc933ef1 241
5092aba5 242static void
17ee7397 243print_reductions (FILE *out, state *s)
5092aba5 244{
17ee7397
PE
245 transitions *trans = s->transitions;
246 reductions *reds = s->reductions;
110ef36a 247 rule *default_reduction = NULL;
87675353
AD
248 size_t width = 0;
249 int i, j;
8f0d265e 250 bool default_reduction_only = true;
5092aba5 251
17ee7397 252 if (reds->num == 0)
80dac38c
AD
253 return;
254
0bf92491 255 if (yydefact[s->number] != 0)
110ef36a 256 default_reduction = &rules[yydefact[s->number] - 1];
5092aba5 257
9d774aff 258 bitset_zero (no_reduce_set);
17ee7397 259 FOR_EACH_SHIFT (trans, i)
9d774aff
JD
260 bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
261 for (i = 0; i < s->errs->num; ++i)
262 if (s->errs->symbols[i])
263 bitset_set (no_reduce_set, s->errs->symbols[i]->number);
5092aba5 264
742e4900 265 /* Compute the width of the lookahead token column. */
110ef36a 266 if (default_reduction)
87675353 267 width = strlen (_("$default"));
cd08e51e 268
742e4900 269 if (reds->lookahead_tokens)
cd08e51e
AD
270 for (i = 0; i < ntokens; i++)
271 {
e9690142
JD
272 bool count = bitset_test (no_reduce_set, i);
273
274 for (j = 0; j < reds->num; ++j)
275 if (bitset_test (reds->lookahead_tokens[j], i))
276 {
277 if (! count)
278 {
279 if (reds->rules[j] != default_reduction)
280 max_length (&width, symbols[i]->tag);
281 count = true;
282 }
283 else
284 {
285 max_length (&width, symbols[i]->tag);
286 }
287 }
cd08e51e 288 }
87675353
AD
289
290 /* Nothing to report. */
291 if (!width)
292 return;
293
294 fputc ('\n', out);
295 width += 2;
296
742e4900
JD
297 /* Report lookahead tokens (or $default) and reductions. */
298 if (reds->lookahead_tokens)
cd08e51e
AD
299 for (i = 0; i < ntokens; i++)
300 {
e9690142
JD
301 bool defaulted = false;
302 bool count = bitset_test (no_reduce_set, i);
7254f6a8 303 if (count)
8f0d265e 304 default_reduction_only = false;
cd08e51e 305
e9690142
JD
306 for (j = 0; j < reds->num; ++j)
307 if (bitset_test (reds->lookahead_tokens[j], i))
308 {
309 if (! count)
310 {
311 if (reds->rules[j] != default_reduction)
7254f6a8 312 {
8f0d265e 313 default_reduction_only = false;
7254f6a8
JD
314 print_reduction (out, width,
315 symbols[i]->tag,
316 reds->rules[j], true);
317 }
e9690142
JD
318 else
319 defaulted = true;
320 count = true;
321 }
322 else
323 {
8f0d265e 324 default_reduction_only = false;
e9690142
JD
325 if (defaulted)
326 print_reduction (out, width,
327 symbols[i]->tag,
328 default_reduction, true);
329 defaulted = false;
330 print_reduction (out, width,
331 symbols[i]->tag,
332 reds->rules[j], false);
333 }
334 }
cd08e51e 335 }
bc933ef1 336
110ef36a 337 if (default_reduction)
7254f6a8 338 {
110ef36a 339 char *default_reductions =
f3bc3386 340 muscle_percent_define_get ("lr.default-reduction");
110ef36a 341 print_reduction (out, width, _("$default"), default_reduction, true);
f518dbaf
AD
342 aver (STREQ (default_reductions, "most")
343 || (STREQ (default_reductions, "consistent")
8f0d265e 344 && default_reduction_only)
7254f6a8 345 || (reds->num == 1 && reds->rules[0]->number == 0));
a2c525b3 346 (void) default_reduction_only;
110ef36a 347 free (default_reductions);
7254f6a8 348 }
5092aba5
AD
349}
350
351
bc933ef1
AD
352/*--------------------------------------------------------------.
353| Report on OUT all the actions (shifts, gotos, reductions, and |
17ee7397 354| explicit erros from %nonassoc) of S. |
bc933ef1
AD
355`--------------------------------------------------------------*/
356
5092aba5 357static void
17ee7397 358print_actions (FILE *out, state *s)
5092aba5 359{
87675353 360 /* Print shifts. */
17ee7397
PE
361 print_transitions (s, out, true);
362 print_errs (out, s);
363 print_reductions (out, s);
87675353 364 /* Print gotos. */
17ee7397 365 print_transitions (s, out, false);
5092aba5
AD
366}
367
bc933ef1 368
17ee7397
PE
369/*----------------------------------.
370| Report all the data on S on OUT. |
371`----------------------------------*/
87675353 372
07a58c13 373static void
17ee7397 374print_state (FILE *out, state *s)
07a58c13 375{
342b8b6e 376 fputs ("\n\n", out);
d42fe46e 377 fprintf (out, _("State %d"), s->number);
87675353 378 fputc ('\n', out);
17ee7397
PE
379 print_core (out, s);
380 print_actions (out, s);
381 if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
7ea9a33f
AD
382 {
383 fputc ('\n', out);
17ee7397 384 fputs (s->solved_conflicts, out);
7ea9a33f 385 }
07a58c13
AD
386}
387\f
388/*-----------------------------------------.
389| Print information on the whole grammar. |
390`-----------------------------------------*/
391
72e727f2
AD
392#define END_TEST(End) \
393 do { \
394 if (column + strlen (buffer) > (End)) \
395 { \
396 fprintf (out, "%s\n ", buffer); \
397 column = 3; \
398 buffer[0] = 0; \
399 } \
400 } while (0)
e06f0c34 401
07a58c13 402
4a120d45 403static void
342b8b6e 404print_grammar (FILE *out)
e06f0c34 405{
17ee7397 406 symbol_number i;
e06f0c34
RS
407 char buffer[90];
408 int column = 0;
409
6b98e4b5 410 grammar_rules_print (out);
e06f0c34
RS
411
412 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 413 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 414 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 415 if (token_translations[i] != undeftoken->number)
342b8b6e 416 {
e9690142
JD
417 const char *tag = symbols[token_translations[i]]->tag;
418 rule_number r;
419 item_number *rhsp;
420
421 buffer[0] = 0;
422 column = strlen (tag);
423 fputs (tag, out);
424 END_TEST (65);
425 sprintf (buffer, " (%d)", i);
426
427 for (r = 0; r < nrules; r++)
428 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
429 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
430 {
431 END_TEST (65);
432 sprintf (buffer + strlen (buffer), " %d", r);
433 break;
434 }
435 fprintf (out, "%s\n", buffer);
342b8b6e 436 }
d2d1b42b
AD
437 fputs ("\n\n", out);
438
342b8b6e 439
d2d1b42b 440 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 441 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
442 {
443 int left_count = 0, right_count = 0;
17ee7397 444 rule_number r;
97650f4e 445 const char *tag = symbols[i]->tag;
e06f0c34 446
4b3d3a8e 447 for (r = 0; r < nrules; r++)
e9690142
JD
448 {
449 item_number *rhsp;
450 if (rules[r].lhs->number == i)
451 left_count++;
452 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
453 if (item_number_as_symbol_number (*rhsp) == i)
454 {
455 right_count++;
456 break;
457 }
458 }
e06f0c34
RS
459
460 buffer[0] = 0;
6b98e4b5
AD
461 fputs (tag, out);
462 column = strlen (tag);
e06f0c34
RS
463 sprintf (buffer, " (%d)", i);
464 END_TEST (0);
465
466 if (left_count > 0)
e9690142
JD
467 {
468 END_TEST (65);
469 sprintf (buffer + strlen (buffer), _(" on left:"));
470
471 for (r = 0; r < nrules; r++)
472 {
473 if (rules[r].lhs->number == i)
474 {
475 END_TEST (65);
476 sprintf (buffer + strlen (buffer), " %d", r);
477 }
478 }
479 }
e06f0c34
RS
480
481 if (right_count > 0)
e9690142
JD
482 {
483 if (left_count > 0)
484 sprintf (buffer + strlen (buffer), ",");
485 END_TEST (65);
486 sprintf (buffer + strlen (buffer), _(" on right:"));
487 for (r = 0; r < nrules; r++)
488 {
489 item_number *rhsp;
490 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
491 if (item_number_as_symbol_number (*rhsp) == i)
492 {
493 END_TEST (65);
494 sprintf (buffer + strlen (buffer), " %d", r);
495 break;
496 }
497 }
498 }
342b8b6e 499 fprintf (out, "%s\n", buffer);
e06f0c34
RS
500 }
501}
07a58c13
AD
502\f
503void
504print_results (void)
505{
17ee7397 506 state_number i;
07a58c13 507
64d15509
AD
508 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
509 that conflicts with Posix. */
510 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 511
64d15509 512 reduce_output (out);
c8f002c7 513 grammar_rules_partial_print (out,
e9690142 514 _("Rules useless in parser due to conflicts"),
cff03fb2 515 rule_useless_in_parser_p);
64d15509 516 conflicts_output (out);
342b8b6e 517
64d15509 518 print_grammar (out);
342b8b6e 519
ec3bc396 520 /* If the whole state item sets, not only the kernels, are wanted,
45eebca4 521 'closure' will be run, which needs memory allocation/deallocation. */
ec3bc396 522 if (report_flag & report_itemsets)
9e7f6bbd 523 new_closure (nritems);
5092aba5 524 /* Storage for print_reductions. */
9d774aff 525 no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
64d15509 526 for (i = 0; i < nstates; i++)
29e88316 527 print_state (out, states[i]);
9d774aff 528 bitset_free (no_reduce_set);
ec3bc396 529 if (report_flag & report_itemsets)
64d15509
AD
530 free_closure ();
531
532 xfclose (out);
07a58c13 533}