]> git.saurik.com Git - bison.git/blame - src/print.c
Implement %define lr.default_rules.
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
a737b216 2
7254f6a8
JD
3 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005,
4 2007, 2009 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"
7254f6a8 34#include "muscle-tab.h"
d7913476 35#include "print.h"
17ee7397 36#include "reader.h"
09b503c8 37#include "reduce.h"
17ee7397
PE
38#include "state.h"
39#include "symtab.h"
0bf92491 40#include "tables.h"
e06f0c34 41
9d774aff 42static bitset no_reduce_set;
5092aba5 43
07a58c13 44#if 0
4a120d45 45static void
d2729d44 46print_token (int extnum, int token)
e06f0c34 47{
342b8b6e 48 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 49}
4a120d45 50#endif
e06f0c34 51
07a58c13 52\f
87675353
AD
53
54/*---------------------------------------.
55| *WIDTH := max (*WIDTH, strlen (STR)). |
56`---------------------------------------*/
57
58static void
59max_length (size_t *width, const char *str)
60{
61 size_t len = strlen (str);
62 if (len > *width)
63 *width = len;
64}
65
342b8b6e 66/*--------------------------------.
07a58c13 67| Report information on a state. |
342b8b6e 68`--------------------------------*/
e06f0c34 69
4a120d45 70static void
17ee7397 71print_core (FILE *out, state *s)
e06f0c34 72{
f6fbd3da 73 size_t i;
17ee7397 74 item_number *sitems = s->items;
f6fbd3da 75 size_t snritems = s->nitems;
17ee7397 76 symbol *previous_lhs = NULL;
e06f0c34 77
ec3bc396
AD
78 /* Output all the items of a state, not only its kernel. */
79 if (report_flag & report_itemsets)
43168960 80 {
5123689b 81 closure (sitems, snritems);
43168960 82 sitems = itemset;
b09f4f48 83 snritems = nitemset;
43168960 84 }
e06f0c34 85
ce4ccb4b
AD
86 if (!snritems)
87 return;
e06f0c34 88
87675353
AD
89 fputc ('\n', out);
90
ce4ccb4b
AD
91 for (i = 0; i < snritems; i++)
92 {
17ee7397
PE
93 item_number *sp;
94 item_number *sp1;
a737b216 95 rule_number r;
e06f0c34 96
ce4ccb4b 97 sp1 = sp = ritem + sitems[i];
e06f0c34 98
ce4ccb4b
AD
99 while (*sp >= 0)
100 sp++;
e06f0c34 101
17ee7397 102 r = item_number_as_rule_number (*sp);
e06f0c34 103
17ee7397
PE
104 rule_lhs_print (&rules[r], previous_lhs, out);
105 previous_lhs = rules[r].lhs;
43168960 106
17ee7397 107 for (sp = rules[r].rhs; sp < sp1; sp++)
97650f4e 108 fprintf (out, " %s", symbols[*sp]->tag);
ce4ccb4b
AD
109 fputs (" .", out);
110 for (/* Nothing */; *sp >= 0; ++sp)
97650f4e 111 fprintf (out, " %s", symbols[*sp]->tag);
d4e7d3a1 112
742e4900 113 /* Display the lookahead tokens? */
a0de5091
JD
114 if (report_flag & report_lookahead_tokens
115 && item_number_is_rule_number (*sp1))
742e4900 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;
7254f6a8 248 bool non_default_action = false;
5092aba5 249
17ee7397 250 if (reds->num == 0)
80dac38c
AD
251 return;
252
0bf92491
JD
253 if (yydefact[s->number] != 0)
254 default_rule = &rules[yydefact[s->number] - 1];
5092aba5 255
9d774aff 256 bitset_zero (no_reduce_set);
17ee7397 257 FOR_EACH_SHIFT (trans, i)
9d774aff
JD
258 bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
259 for (i = 0; i < s->errs->num; ++i)
260 if (s->errs->symbols[i])
261 bitset_set (no_reduce_set, s->errs->symbols[i]->number);
5092aba5 262
742e4900 263 /* Compute the width of the lookahead token column. */
87675353
AD
264 if (default_rule)
265 width = strlen (_("$default"));
cd08e51e 266
742e4900 267 if (reds->lookahead_tokens)
cd08e51e
AD
268 for (i = 0; i < ntokens; i++)
269 {
9d774aff 270 bool count = bitset_test (no_reduce_set, i);
cd08e51e 271
17ee7397 272 for (j = 0; j < reds->num; ++j)
742e4900 273 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 274 {
d0829076 275 if (! count)
cd08e51e 276 {
17ee7397 277 if (reds->rules[j] != default_rule)
cd08e51e 278 max_length (&width, symbols[i]->tag);
d0829076 279 count = true;
cd08e51e
AD
280 }
281 else
282 {
97650f4e 283 max_length (&width, symbols[i]->tag);
cd08e51e
AD
284 }
285 }
286 }
87675353
AD
287
288 /* Nothing to report. */
289 if (!width)
290 return;
291
292 fputc ('\n', out);
293 width += 2;
294
742e4900
JD
295 /* Report lookahead tokens (or $default) and reductions. */
296 if (reds->lookahead_tokens)
cd08e51e
AD
297 for (i = 0; i < ntokens; i++)
298 {
d0829076 299 bool defaulted = false;
9d774aff 300 bool count = bitset_test (no_reduce_set, i);
7254f6a8
JD
301 if (count)
302 non_default_action = true;
cd08e51e 303
17ee7397 304 for (j = 0; j < reds->num; ++j)
742e4900 305 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 306 {
d0829076 307 if (! count)
cd08e51e 308 {
17ee7397 309 if (reds->rules[j] != default_rule)
7254f6a8
JD
310 {
311 non_default_action = true;
312 print_reduction (out, width,
313 symbols[i]->tag,
314 reds->rules[j], true);
315 }
cd08e51e 316 else
d0829076
PE
317 defaulted = true;
318 count = true;
cd08e51e
AD
319 }
320 else
321 {
7254f6a8 322 non_default_action = true;
cd08e51e
AD
323 if (defaulted)
324 print_reduction (out, width,
325 symbols[i]->tag,
8307162d 326 default_rule, true);
d0829076 327 defaulted = false;
87675353 328 print_reduction (out, width,
97650f4e 329 symbols[i]->tag,
17ee7397 330 reds->rules[j], false);
cd08e51e
AD
331 }
332 }
333 }
bc933ef1
AD
334
335 if (default_rule)
7254f6a8
JD
336 {
337 char *default_rules = muscle_percent_define_get ("lr.default_rules");
338 print_reduction (out, width, _("$default"), default_rule, true);
339 aver (0 == strcmp (default_rules, "all")
340 || (0 == strcmp (default_rules, "consistent")
341 && !non_default_action)
342 || (reds->num == 1 && reds->rules[0]->number == 0));
343 free (default_rules);
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);
17ee7397 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
72e727f2
AD
388#define END_TEST(End) \
389 do { \
390 if (column + strlen (buffer) > (End)) \
391 { \
392 fprintf (out, "%s\n ", buffer); \
393 column = 3; \
394 buffer[0] = 0; \
395 } \
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}