]> git.saurik.com Git - bison.git/blame - src/print.c
Improve handling of multiple S/R conflicts in the same state and of S/R
[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
c29240e7
AD
8 Bison is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
e06f0c34 12
c29240e7
AD
13 Bison is distributed in the hope that it will be useful,
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
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to
0fb669f9
PE
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
e06f0c34 22
2cec9080 23#include <config.h>
e06f0c34 24#include "system.h"
17ee7397
PE
25
26#include <bitset.h>
27#include <quotearg.h>
28
b2ca4022 29#include "LR0.h"
17ee7397 30#include "closure.h"
0619caf0 31#include "conflicts.h"
17ee7397 32#include "files.h"
07a58c13 33#include "getargs.h"
17ee7397
PE
34#include "gram.h"
35#include "lalr.h"
d7913476 36#include "print.h"
17ee7397 37#include "reader.h"
09b503c8 38#include "reduce.h"
17ee7397
PE
39#include "state.h"
40#include "symtab.h"
0bf92491 41#include "tables.h"
e06f0c34 42
9d774aff 43static bitset no_reduce_set;
5092aba5 44
07a58c13 45#if 0
4a120d45 46static void
d2729d44 47print_token (int extnum, int token)
e06f0c34 48{
342b8b6e 49 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 50}
4a120d45 51#endif
e06f0c34 52
07a58c13 53\f
87675353
AD
54
55/*---------------------------------------.
56| *WIDTH := max (*WIDTH, strlen (STR)). |
57`---------------------------------------*/
58
59static void
60max_length (size_t *width, const char *str)
61{
62 size_t len = strlen (str);
63 if (len > *width)
64 *width = len;
65}
66
342b8b6e 67/*--------------------------------.
07a58c13 68| Report information on a state. |
342b8b6e 69`--------------------------------*/
e06f0c34 70
4a120d45 71static void
17ee7397 72print_core (FILE *out, state *s)
e06f0c34 73{
f6fbd3da 74 size_t i;
17ee7397 75 item_number *sitems = s->items;
f6fbd3da 76 size_t snritems = s->nitems;
17ee7397 77 symbol *previous_lhs = NULL;
e06f0c34 78
ec3bc396
AD
79 /* Output all the items of a state, not only its kernel. */
80 if (report_flag & report_itemsets)
43168960 81 {
5123689b 82 closure (sitems, snritems);
43168960 83 sitems = itemset;
b09f4f48 84 snritems = nitemset;
43168960 85 }
e06f0c34 86
ce4ccb4b
AD
87 if (!snritems)
88 return;
e06f0c34 89
87675353
AD
90 fputc ('\n', out);
91
ce4ccb4b
AD
92 for (i = 0; i < snritems; i++)
93 {
17ee7397
PE
94 item_number *sp;
95 item_number *sp1;
a737b216 96 rule_number r;
e06f0c34 97
ce4ccb4b 98 sp1 = sp = ritem + sitems[i];
e06f0c34 99
ce4ccb4b
AD
100 while (*sp >= 0)
101 sp++;
e06f0c34 102
17ee7397 103 r = item_number_as_rule_number (*sp);
e06f0c34 104
17ee7397
PE
105 rule_lhs_print (&rules[r], previous_lhs, out);
106 previous_lhs = rules[r].lhs;
43168960 107
17ee7397 108 for (sp = rules[r].rhs; sp < sp1; sp++)
97650f4e 109 fprintf (out, " %s", symbols[*sp]->tag);
ce4ccb4b
AD
110 fputs (" .", out);
111 for (/* Nothing */; *sp >= 0; ++sp)
97650f4e 112 fprintf (out, " %s", symbols[*sp]->tag);
d4e7d3a1 113
742e4900
JD
114 /* Display the lookahead tokens? */
115 if (report_flag & report_lookahead_tokens)
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;
245 rule *default_rule = NULL;
87675353
AD
246 size_t width = 0;
247 int i, j;
5092aba5 248
17ee7397 249 if (reds->num == 0)
80dac38c
AD
250 return;
251
0bf92491
JD
252 if (yydefact[s->number] != 0)
253 default_rule = &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. */
87675353
AD
263 if (default_rule)
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 {
17ee7397 276 if (reds->rules[j] != default_rule)
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);
cd08e51e 300
17ee7397 301 for (j = 0; j < reds->num; ++j)
742e4900 302 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 303 {
d0829076 304 if (! count)
cd08e51e 305 {
17ee7397 306 if (reds->rules[j] != default_rule)
cd08e51e
AD
307 print_reduction (out, width,
308 symbols[i]->tag,
17ee7397 309 reds->rules[j], true);
cd08e51e 310 else
d0829076
PE
311 defaulted = true;
312 count = true;
cd08e51e
AD
313 }
314 else
315 {
316 if (defaulted)
317 print_reduction (out, width,
318 symbols[i]->tag,
8307162d 319 default_rule, true);
d0829076 320 defaulted = false;
87675353 321 print_reduction (out, width,
97650f4e 322 symbols[i]->tag,
17ee7397 323 reds->rules[j], false);
cd08e51e
AD
324 }
325 }
326 }
bc933ef1
AD
327
328 if (default_rule)
87675353 329 print_reduction (out, width,
8307162d 330 _("$default"), default_rule, true);
5092aba5
AD
331}
332
333
bc933ef1
AD
334/*--------------------------------------------------------------.
335| Report on OUT all the actions (shifts, gotos, reductions, and |
17ee7397 336| explicit erros from %nonassoc) of S. |
bc933ef1
AD
337`--------------------------------------------------------------*/
338
5092aba5 339static void
17ee7397 340print_actions (FILE *out, state *s)
5092aba5 341{
87675353 342 /* Print shifts. */
17ee7397
PE
343 print_transitions (s, out, true);
344 print_errs (out, s);
345 print_reductions (out, s);
87675353 346 /* Print gotos. */
17ee7397 347 print_transitions (s, out, false);
5092aba5
AD
348}
349
bc933ef1 350
17ee7397
PE
351/*----------------------------------.
352| Report all the data on S on OUT. |
353`----------------------------------*/
87675353 354
07a58c13 355static void
17ee7397 356print_state (FILE *out, state *s)
07a58c13 357{
342b8b6e 358 fputs ("\n\n", out);
17ee7397 359 fprintf (out, _("state %d"), s->number);
87675353 360 fputc ('\n', out);
17ee7397
PE
361 print_core (out, s);
362 print_actions (out, s);
363 if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
7ea9a33f
AD
364 {
365 fputc ('\n', out);
17ee7397 366 fputs (s->solved_conflicts, out);
7ea9a33f 367 }
07a58c13
AD
368}
369\f
370/*-----------------------------------------.
371| Print information on the whole grammar. |
372`-----------------------------------------*/
373
342b8b6e
AD
374#define END_TEST(End) \
375do { \
376 if (column + strlen(buffer) > (End)) \
377 { \
378 fprintf (out, "%s\n ", buffer); \
379 column = 3; \
380 buffer[0] = 0; \
381 } \
ff4423cc 382} while (0)
e06f0c34 383
07a58c13 384
4a120d45 385static void
342b8b6e 386print_grammar (FILE *out)
e06f0c34 387{
17ee7397 388 symbol_number i;
e06f0c34
RS
389 char buffer[90];
390 int column = 0;
391
6b98e4b5 392 grammar_rules_print (out);
e06f0c34
RS
393
394 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 395 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 396 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 397 if (token_translations[i] != undeftoken->number)
342b8b6e 398 {
97650f4e 399 const char *tag = symbols[token_translations[i]]->tag;
17ee7397
PE
400 rule_number r;
401 item_number *rhsp;
9222837b 402
342b8b6e 403 buffer[0] = 0;
6b98e4b5
AD
404 column = strlen (tag);
405 fputs (tag, out);
342b8b6e
AD
406 END_TEST (50);
407 sprintf (buffer, " (%d)", i);
e06f0c34 408
4b3d3a8e 409 for (r = 0; r < nrules; r++)
9222837b
AD
410 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
411 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
412 {
413 END_TEST (65);
4b3d3a8e 414 sprintf (buffer + strlen (buffer), " %d", r);
342b8b6e
AD
415 break;
416 }
417 fprintf (out, "%s\n", buffer);
418 }
d2d1b42b
AD
419 fputs ("\n\n", out);
420
342b8b6e 421
d2d1b42b 422 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 423 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
424 {
425 int left_count = 0, right_count = 0;
17ee7397 426 rule_number r;
97650f4e 427 const char *tag = symbols[i]->tag;
e06f0c34 428
4b3d3a8e 429 for (r = 0; r < nrules; r++)
e06f0c34 430 {
17ee7397 431 item_number *rhsp;
6b98e4b5 432 if (rules[r].lhs->number == i)
e06f0c34 433 left_count++;
9222837b
AD
434 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
435 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
436 {
437 right_count++;
438 break;
439 }
440 }
441
442 buffer[0] = 0;
6b98e4b5
AD
443 fputs (tag, out);
444 column = strlen (tag);
e06f0c34
RS
445 sprintf (buffer, " (%d)", i);
446 END_TEST (0);
447
448 if (left_count > 0)
449 {
450 END_TEST (50);
c29240e7 451 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 452
4b3d3a8e 453 for (r = 0; r < nrules; r++)
e06f0c34
RS
454 {
455 END_TEST (65);
6b98e4b5 456 if (rules[r].lhs->number == i)
4b3d3a8e 457 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
458 }
459 }
460
461 if (right_count > 0)
462 {
463 if (left_count > 0)
c29240e7 464 sprintf (buffer + strlen (buffer), ",");
e06f0c34 465 END_TEST (50);
c29240e7 466 sprintf (buffer + strlen (buffer), _(" on right:"));
4b3d3a8e 467 for (r = 0; r < nrules; r++)
e06f0c34 468 {
17ee7397 469 item_number *rhsp;
9222837b
AD
470 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
471 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
472 {
473 END_TEST (65);
4b3d3a8e 474 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
475 break;
476 }
477 }
478 }
342b8b6e 479 fprintf (out, "%s\n", buffer);
e06f0c34
RS
480 }
481}
07a58c13
AD
482\f
483void
484print_results (void)
485{
17ee7397 486 state_number i;
07a58c13 487
64d15509
AD
488 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
489 that conflicts with Posix. */
490 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 491
64d15509 492 reduce_output (out);
c8f002c7
AD
493 grammar_rules_partial_print (out,
494 _("Rules never reduced"), rule_never_reduced_p);
64d15509 495 conflicts_output (out);
342b8b6e 496
64d15509 497 print_grammar (out);
342b8b6e 498
ec3bc396
AD
499 /* If the whole state item sets, not only the kernels, are wanted,
500 `closure' will be run, which needs memory allocation/deallocation. */
501 if (report_flag & report_itemsets)
9e7f6bbd 502 new_closure (nritems);
5092aba5 503 /* Storage for print_reductions. */
9d774aff 504 no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
64d15509 505 for (i = 0; i < nstates; i++)
29e88316 506 print_state (out, states[i]);
9d774aff 507 bitset_free (no_reduce_set);
ec3bc396 508 if (report_flag & report_itemsets)
64d15509
AD
509 free_closure ();
510
511 xfclose (out);
07a58c13 512}