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