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