]> git.saurik.com Git - bison.git/blame - src/print.c
2007-11-08 Paolo Bonzini <bonzini@gnu.org>
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
a737b216 2
75ad86ee 3 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005, 2007
b0299a2e 4 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"
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;
244 rule *default_rule = NULL;
87675353
AD
245 size_t width = 0;
246 int i, j;
5092aba5 247
17ee7397 248 if (reds->num == 0)
80dac38c
AD
249 return;
250
0bf92491
JD
251 if (yydefact[s->number] != 0)
252 default_rule = &rules[yydefact[s->number] - 1];
5092aba5 253
9d774aff 254 bitset_zero (no_reduce_set);
17ee7397 255 FOR_EACH_SHIFT (trans, i)
9d774aff
JD
256 bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
257 for (i = 0; i < s->errs->num; ++i)
258 if (s->errs->symbols[i])
259 bitset_set (no_reduce_set, s->errs->symbols[i]->number);
5092aba5 260
742e4900 261 /* Compute the width of the lookahead token column. */
87675353
AD
262 if (default_rule)
263 width = strlen (_("$default"));
cd08e51e 264
742e4900 265 if (reds->lookahead_tokens)
cd08e51e
AD
266 for (i = 0; i < ntokens; i++)
267 {
9d774aff 268 bool count = bitset_test (no_reduce_set, i);
cd08e51e 269
17ee7397 270 for (j = 0; j < reds->num; ++j)
742e4900 271 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 272 {
d0829076 273 if (! count)
cd08e51e 274 {
17ee7397 275 if (reds->rules[j] != default_rule)
cd08e51e 276 max_length (&width, symbols[i]->tag);
d0829076 277 count = true;
cd08e51e
AD
278 }
279 else
280 {
97650f4e 281 max_length (&width, symbols[i]->tag);
cd08e51e
AD
282 }
283 }
284 }
87675353
AD
285
286 /* Nothing to report. */
287 if (!width)
288 return;
289
290 fputc ('\n', out);
291 width += 2;
292
742e4900
JD
293 /* Report lookahead tokens (or $default) and reductions. */
294 if (reds->lookahead_tokens)
cd08e51e
AD
295 for (i = 0; i < ntokens; i++)
296 {
d0829076 297 bool defaulted = false;
9d774aff 298 bool count = bitset_test (no_reduce_set, i);
cd08e51e 299
17ee7397 300 for (j = 0; j < reds->num; ++j)
742e4900 301 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 302 {
d0829076 303 if (! count)
cd08e51e 304 {
17ee7397 305 if (reds->rules[j] != default_rule)
cd08e51e
AD
306 print_reduction (out, width,
307 symbols[i]->tag,
17ee7397 308 reds->rules[j], true);
cd08e51e 309 else
d0829076
PE
310 defaulted = true;
311 count = true;
cd08e51e
AD
312 }
313 else
314 {
315 if (defaulted)
316 print_reduction (out, width,
317 symbols[i]->tag,
8307162d 318 default_rule, true);
d0829076 319 defaulted = false;
87675353 320 print_reduction (out, width,
97650f4e 321 symbols[i]->tag,
17ee7397 322 reds->rules[j], false);
cd08e51e
AD
323 }
324 }
325 }
bc933ef1
AD
326
327 if (default_rule)
87675353 328 print_reduction (out, width,
8307162d 329 _("$default"), default_rule, true);
5092aba5
AD
330}
331
332
bc933ef1
AD
333/*--------------------------------------------------------------.
334| Report on OUT all the actions (shifts, gotos, reductions, and |
17ee7397 335| explicit erros from %nonassoc) of S. |
bc933ef1
AD
336`--------------------------------------------------------------*/
337
5092aba5 338static void
17ee7397 339print_actions (FILE *out, state *s)
5092aba5 340{
87675353 341 /* Print shifts. */
17ee7397
PE
342 print_transitions (s, out, true);
343 print_errs (out, s);
344 print_reductions (out, s);
87675353 345 /* Print gotos. */
17ee7397 346 print_transitions (s, out, false);
5092aba5
AD
347}
348
bc933ef1 349
17ee7397
PE
350/*----------------------------------.
351| Report all the data on S on OUT. |
352`----------------------------------*/
87675353 353
07a58c13 354static void
17ee7397 355print_state (FILE *out, state *s)
07a58c13 356{
342b8b6e 357 fputs ("\n\n", out);
17ee7397 358 fprintf (out, _("state %d"), s->number);
87675353 359 fputc ('\n', out);
17ee7397
PE
360 print_core (out, s);
361 print_actions (out, s);
362 if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
7ea9a33f
AD
363 {
364 fputc ('\n', out);
17ee7397 365 fputs (s->solved_conflicts, out);
7ea9a33f 366 }
07a58c13
AD
367}
368\f
369/*-----------------------------------------.
370| Print information on the whole grammar. |
371`-----------------------------------------*/
372
342b8b6e
AD
373#define END_TEST(End) \
374do { \
375 if (column + strlen(buffer) > (End)) \
376 { \
377 fprintf (out, "%s\n ", buffer); \
378 column = 3; \
379 buffer[0] = 0; \
380 } \
ff4423cc 381} while (0)
e06f0c34 382
07a58c13 383
4a120d45 384static void
342b8b6e 385print_grammar (FILE *out)
e06f0c34 386{
17ee7397 387 symbol_number i;
e06f0c34
RS
388 char buffer[90];
389 int column = 0;
390
6b98e4b5 391 grammar_rules_print (out);
e06f0c34
RS
392
393 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 394 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 395 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 396 if (token_translations[i] != undeftoken->number)
342b8b6e 397 {
97650f4e 398 const char *tag = symbols[token_translations[i]]->tag;
17ee7397
PE
399 rule_number r;
400 item_number *rhsp;
9222837b 401
342b8b6e 402 buffer[0] = 0;
6b98e4b5
AD
403 column = strlen (tag);
404 fputs (tag, out);
21f1b063 405 END_TEST (65);
342b8b6e 406 sprintf (buffer, " (%d)", i);
e06f0c34 407
4b3d3a8e 408 for (r = 0; r < nrules; r++)
9222837b
AD
409 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
410 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
411 {
412 END_TEST (65);
4b3d3a8e 413 sprintf (buffer + strlen (buffer), " %d", r);
342b8b6e
AD
414 break;
415 }
416 fprintf (out, "%s\n", buffer);
417 }
d2d1b42b
AD
418 fputs ("\n\n", out);
419
342b8b6e 420
d2d1b42b 421 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 422 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
423 {
424 int left_count = 0, right_count = 0;
17ee7397 425 rule_number r;
97650f4e 426 const char *tag = symbols[i]->tag;
e06f0c34 427
4b3d3a8e 428 for (r = 0; r < nrules; r++)
e06f0c34 429 {
17ee7397 430 item_number *rhsp;
6b98e4b5 431 if (rules[r].lhs->number == i)
e06f0c34 432 left_count++;
9222837b
AD
433 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
434 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
435 {
436 right_count++;
437 break;
438 }
439 }
440
441 buffer[0] = 0;
6b98e4b5
AD
442 fputs (tag, out);
443 column = strlen (tag);
e06f0c34
RS
444 sprintf (buffer, " (%d)", i);
445 END_TEST (0);
446
447 if (left_count > 0)
448 {
21f1b063 449 END_TEST (65);
c29240e7 450 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 451
4b3d3a8e 452 for (r = 0; r < nrules; r++)
e06f0c34 453 {
6b98e4b5 454 if (rules[r].lhs->number == i)
21f1b063
JD
455 {
456 END_TEST (65);
457 sprintf (buffer + strlen (buffer), " %d", r);
458 }
e06f0c34
RS
459 }
460 }
461
462 if (right_count > 0)
463 {
464 if (left_count > 0)
c29240e7 465 sprintf (buffer + strlen (buffer), ",");
21f1b063 466 END_TEST (65);
c29240e7 467 sprintf (buffer + strlen (buffer), _(" on right:"));
4b3d3a8e 468 for (r = 0; r < nrules; r++)
e06f0c34 469 {
17ee7397 470 item_number *rhsp;
9222837b
AD
471 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
472 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
473 {
474 END_TEST (65);
4b3d3a8e 475 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
476 break;
477 }
478 }
479 }
342b8b6e 480 fprintf (out, "%s\n", buffer);
e06f0c34
RS
481 }
482}
07a58c13
AD
483\f
484void
485print_results (void)
486{
17ee7397 487 state_number i;
07a58c13 488
64d15509
AD
489 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
490 that conflicts with Posix. */
491 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 492
64d15509 493 reduce_output (out);
c8f002c7
AD
494 grammar_rules_partial_print (out,
495 _("Rules never reduced"), rule_never_reduced_p);
64d15509 496 conflicts_output (out);
342b8b6e 497
64d15509 498 print_grammar (out);
342b8b6e 499
ec3bc396
AD
500 /* If the whole state item sets, not only the kernels, are wanted,
501 `closure' will be run, which needs memory allocation/deallocation. */
502 if (report_flag & report_itemsets)
9e7f6bbd 503 new_closure (nritems);
5092aba5 504 /* Storage for print_reductions. */
9d774aff 505 no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
64d15509 506 for (i = 0; i < nstates; i++)
29e88316 507 print_state (out, states[i]);
9d774aff 508 bitset_free (no_reduce_set);
ec3bc396 509 if (report_flag & report_itemsets)
64d15509
AD
510 free_closure ();
511
512 xfclose (out);
07a58c13 513}