]> git.saurik.com Git - bison.git/blame - src/print.c
xml: match DOT output and xml2dot.xsl processing
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
a737b216 2
c932d613 3 Copyright (C) 1984, 1986, 1989, 2000-2005, 2007, 2009-2012 Free
ea0a7676 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"
23ec25b7 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
AD
98 while (*sp >= 0)
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++)
97650f4e 107 fprintf (out, " %s", symbols[*sp]->tag);
ce4ccb4b
AD
108 fputs (" .", out);
109 for (/* Nothing */; *sp >= 0; ++sp)
97650f4e 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))
742e4900 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)
137 && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
d954473d 138 {
17ee7397
PE
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)
153 && TRANSITION_IS_SHIFT (trans, i) == display_transitions_p)
87675353 154 {
17ee7397
PE
155 symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)];
156 const char *tag = sym->tag;
157 state *s1 = trans->states[i];
87675353
AD
158 int j;
159
160 fprintf (out, " %s", tag);
161 for (j = width - strlen (tag); j > 0; --j)
162 fputc (' ', out);
ccaf65bc 163 if (display_transitions_p)
17ee7397 164 fprintf (out, _("shift, and go to state %d\n"), s1->number);
87675353 165 else
17ee7397 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 {
640748ee 198 const char *tag = errp->symbols[i]->tag;
87675353
AD
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);
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,
742e4900 216 const char *lookahead_token,
17ee7397 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;
620b5727 244 rule *default_reduction = NULL;
87675353
AD
245 size_t width = 0;
246 int i, j;
379261b3 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)
620b5727 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. */
620b5727 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 {
9d774aff 269 bool count = bitset_test (no_reduce_set, i);
cd08e51e 270
17ee7397 271 for (j = 0; j < reds->num; ++j)
742e4900 272 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 273 {
d0829076 274 if (! count)
cd08e51e 275 {
620b5727 276 if (reds->rules[j] != default_reduction)
cd08e51e 277 max_length (&width, symbols[i]->tag);
d0829076 278 count = true;
cd08e51e
AD
279 }
280 else
281 {
97650f4e 282 max_length (&width, symbols[i]->tag);
cd08e51e
AD
283 }
284 }
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 {
d0829076 298 bool defaulted = false;
9d774aff 299 bool count = bitset_test (no_reduce_set, i);
03c07b03 300 if (count)
379261b3 301 default_reduction_only = false;
cd08e51e 302
17ee7397 303 for (j = 0; j < reds->num; ++j)
742e4900 304 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 305 {
d0829076 306 if (! count)
cd08e51e 307 {
620b5727 308 if (reds->rules[j] != default_reduction)
03c07b03 309 {
379261b3 310 default_reduction_only = false;
03c07b03
JD
311 print_reduction (out, width,
312 symbols[i]->tag,
313 reds->rules[j], true);
314 }
cd08e51e 315 else
d0829076
PE
316 defaulted = true;
317 count = true;
cd08e51e
AD
318 }
319 else
320 {
379261b3 321 default_reduction_only = false;
cd08e51e
AD
322 if (defaulted)
323 print_reduction (out, width,
324 symbols[i]->tag,
620b5727 325 default_reduction, true);
d0829076 326 defaulted = false;
87675353 327 print_reduction (out, width,
97650f4e 328 symbols[i]->tag,
17ee7397 329 reds->rules[j], false);
cd08e51e
AD
330 }
331 }
332 }
bc933ef1 333
620b5727 334 if (default_reduction)
03c07b03 335 {
620b5727 336 char *default_reductions =
1d0f55cc 337 muscle_percent_define_get ("lr.default-reductions");
620b5727 338 print_reduction (out, width, _("$default"), default_reduction, true);
a6e5a280 339 aver (0 == strcmp (default_reductions, "most")
620b5727 340 || (0 == strcmp (default_reductions, "consistent")
379261b3 341 && default_reduction_only)
03c07b03 342 || (reds->num == 1 && reds->rules[0]->number == 0));
620b5727 343 free (default_reductions);
03c07b03 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);
d42fe46e 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
342b8b6e
AD
388#define END_TEST(End) \
389do { \
390 if (column + strlen(buffer) > (End)) \
391 { \
392 fprintf (out, "%s\n ", buffer); \
393 column = 3; \
394 buffer[0] = 0; \
395 } \
ff4423cc 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 {
97650f4e 413 const char *tag = symbols[token_translations[i]]->tag;
17ee7397
PE
414 rule_number r;
415 item_number *rhsp;
9222837b 416
342b8b6e 417 buffer[0] = 0;
6b98e4b5
AD
418 column = strlen (tag);
419 fputs (tag, out);
21f1b063 420 END_TEST (65);
342b8b6e 421 sprintf (buffer, " (%d)", i);
e06f0c34 422
4b3d3a8e 423 for (r = 0; r < nrules; r++)
9222837b
AD
424 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
425 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
426 {
427 END_TEST (65);
4b3d3a8e 428 sprintf (buffer + strlen (buffer), " %d", r);
342b8b6e
AD
429 break;
430 }
431 fprintf (out, "%s\n", buffer);
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++)
e06f0c34 444 {
17ee7397 445 item_number *rhsp;
6b98e4b5 446 if (rules[r].lhs->number == i)
e06f0c34 447 left_count++;
9222837b
AD
448 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
449 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
450 {
451 right_count++;
452 break;
453 }
454 }
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)
463 {
21f1b063 464 END_TEST (65);
c29240e7 465 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 466
4b3d3a8e 467 for (r = 0; r < nrules; r++)
e06f0c34 468 {
6b98e4b5 469 if (rules[r].lhs->number == i)
21f1b063
JD
470 {
471 END_TEST (65);
472 sprintf (buffer + strlen (buffer), " %d", r);
473 }
e06f0c34
RS
474 }
475 }
476
477 if (right_count > 0)
478 {
479 if (left_count > 0)
c29240e7 480 sprintf (buffer + strlen (buffer), ",");
21f1b063 481 END_TEST (65);
c29240e7 482 sprintf (buffer + strlen (buffer), _(" on right:"));
4b3d3a8e 483 for (r = 0; r < nrules; r++)
e06f0c34 484 {
17ee7397 485 item_number *rhsp;
9222837b
AD
486 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
487 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
488 {
489 END_TEST (65);
4b3d3a8e 490 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
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,
cff03fb2
JD
510 _("Rules useless in parser due to conflicts"),
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}