]> git.saurik.com Git - bison.git/blame - src/print.c
(symbol_printers_output): Fix typo that led
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
b0299a2e
AD
2 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002
3 Free Software Foundation, Inc.
e06f0c34 4
c29240e7 5 This file is part of Bison, the GNU Compiler Compiler.
e06f0c34 6
c29240e7
AD
7 Bison is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
e06f0c34 11
c29240e7
AD
12 Bison is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
e06f0c34 16
c29240e7
AD
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
e06f0c34
RS
21
22
e06f0c34 23#include "system.h"
17ee7397
PE
24
25#include <bitset.h>
26#include <quotearg.h>
27
b2ca4022 28#include "LR0.h"
17ee7397 29#include "closure.h"
0619caf0 30#include "conflicts.h"
17ee7397 31#include "files.h"
07a58c13 32#include "getargs.h"
17ee7397
PE
33#include "gram.h"
34#include "lalr.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"
e06f0c34 40
34ba9743
AD
41static bitset shiftset;
42static bitset lookaheadset;
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{
c29240e7 73 int i;
17ee7397
PE
74 item_number *sitems = s->items;
75 int snritems = s->nitems;
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;
5123689b 83 snritems = nritemset;
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;
95 int 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
ce4ccb4b
AD
113 /* Display the lookaheads? */
114 if (report_flag & report_lookaheads)
17ee7397 115 state_rule_lookaheads_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
87675353 134 /* Compute the width of the lookaheads 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
150 /* Report lookaheads 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
87675353 182 /* Compute the width of the lookaheads 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
87675353 194 /* Report lookaheads 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
17ee7397
PE
208/*-------------------------------------------------------------.
209| Return the default rule of S if it has one, NULL otherwise. |
210`-------------------------------------------------------------*/
bc933ef1 211
17ee7397
PE
212static rule *
213state_default_rule (state *s)
bc933ef1 214{
17ee7397
PE
215 reductions *reds = s->reductions;
216 rule *default_rule = NULL;
bc933ef1
AD
217 int cmax = 0;
218 int i;
219
220 /* No need for a lookahead. */
17ee7397
PE
221 if (s->consistent)
222 return reds->rules[0];
bc933ef1
AD
223
224 /* 1. Each reduction is possibly masked by the lookaheads on which
225 we shift (S/R conflicts)... */
226 bitset_zero (shiftset);
227 {
17ee7397
PE
228 transitions *trans = s->transitions;
229 FOR_EACH_SHIFT (trans, i)
640748ee
AD
230 {
231 /* If this state has a shift for the error token, don't use a
bc933ef1 232 default rule. */
17ee7397 233 if (TRANSITION_IS_ERROR (trans, i))
640748ee 234 return NULL;
17ee7397 235 bitset_set (shiftset, TRANSITION_SYMBOL (trans, i));
640748ee 236 }
bc933ef1
AD
237 }
238
239 /* 2. Each reduction is possibly masked by the lookaheads on which
240 we raise an error (due to %nonassoc). */
241 {
17ee7397 242 errs *errp = s->errs;
d2576365
AD
243 for (i = 0; i < errp->num; i++)
244 if (errp->symbols[i])
640748ee 245 bitset_set (shiftset, errp->symbols[i]->number);
bc933ef1
AD
246 }
247
17ee7397 248 for (i = 0; i < reds->num; ++i)
bc933ef1
AD
249 {
250 int count = 0;
251
252 /* How many non-masked lookaheads are there for this reduction?
253 */
17ee7397 254 bitset_andn (lookaheadset, reds->lookaheads[i], shiftset);
bc933ef1
AD
255 count = bitset_count (lookaheadset);
256
257 if (count > cmax)
258 {
259 cmax = count;
17ee7397 260 default_rule = reds->rules[i];
bc933ef1
AD
261 }
262
263 /* 3. And finally, each reduction is possibly masked by previous
264 reductions (in R/R conflicts, we keep the first reductions).
265 */
17ee7397 266 bitset_or (shiftset, shiftset, reds->lookaheads[i]);
bc933ef1
AD
267 }
268
269 return default_rule;
270}
271
272
87675353
AD
273/*--------------------------------------------------------------------.
274| Report a reduction of RULE on LOOKAHEADS (which can be `default'). |
275| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
276| R/R conflicts). |
277`--------------------------------------------------------------------*/
278
279static void
280print_reduction (FILE *out, size_t width,
281 const char *lookahead,
17ee7397 282 rule *r, bool enabled)
87675353
AD
283{
284 int j;
285 fprintf (out, " %s", lookahead);
286 for (j = width - strlen (lookahead); j > 0; --j)
287 fputc (' ', out);
288 if (!enabled)
289 fputc ('[', out);
17ee7397
PE
290 if (r->number)
291 fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
e8832397
AD
292 else
293 fprintf (out, _("accept"));
87675353
AD
294 if (!enabled)
295 fputc (']', out);
296 fputc ('\n', out);
297}
298
299
17ee7397
PE
300/*-------------------------------------------.
301| Report on OUT the reduction actions of S. |
302`-------------------------------------------*/
bc933ef1 303
5092aba5 304static void
17ee7397 305print_reductions (FILE *out, state *s)
5092aba5 306{
17ee7397
PE
307 transitions *trans = s->transitions;
308 reductions *reds = s->reductions;
309 rule *default_rule = NULL;
87675353
AD
310 size_t width = 0;
311 int i, j;
5092aba5 312
17ee7397 313 if (reds->num == 0)
80dac38c
AD
314 return;
315
17ee7397 316 default_rule = state_default_rule (s);
5092aba5 317
34ba9743 318 bitset_zero (shiftset);
17ee7397
PE
319 FOR_EACH_SHIFT (trans, i)
320 bitset_set (shiftset, TRANSITION_SYMBOL (trans, i));
5092aba5 321
87675353
AD
322 /* Compute the width of the lookaheads column. */
323 if (default_rule)
324 width = strlen (_("$default"));
cd08e51e 325
17ee7397 326 if (reds->lookaheads)
cd08e51e
AD
327 for (i = 0; i < ntokens; i++)
328 {
329 int count = bitset_test (shiftset, i);
330
17ee7397
PE
331 for (j = 0; j < reds->num; ++j)
332 if (bitset_test (reds->lookaheads[j], i))
cd08e51e
AD
333 {
334 if (count == 0)
335 {
17ee7397 336 if (reds->rules[j] != default_rule)
cd08e51e
AD
337 max_length (&width, symbols[i]->tag);
338 count++;
339 }
340 else
341 {
97650f4e 342 max_length (&width, symbols[i]->tag);
cd08e51e
AD
343 }
344 }
345 }
87675353
AD
346
347 /* Nothing to report. */
348 if (!width)
349 return;
350
351 fputc ('\n', out);
352 width += 2;
353
354 /* Report lookaheads (or $default) and reductions. */
17ee7397 355 if (reds->lookaheads)
cd08e51e
AD
356 for (i = 0; i < ntokens; i++)
357 {
358 int defaulted = 0;
359 int count = bitset_test (shiftset, i);
360
17ee7397
PE
361 for (j = 0; j < reds->num; ++j)
362 if (bitset_test (reds->lookaheads[j], i))
cd08e51e
AD
363 {
364 if (count == 0)
365 {
17ee7397 366 if (reds->rules[j] != default_rule)
cd08e51e
AD
367 print_reduction (out, width,
368 symbols[i]->tag,
17ee7397 369 reds->rules[j], true);
cd08e51e
AD
370 else
371 defaulted = 1;
372 count++;
373 }
374 else
375 {
376 if (defaulted)
377 print_reduction (out, width,
378 symbols[i]->tag,
8307162d 379 default_rule, true);
cd08e51e 380 defaulted = 0;
87675353 381 print_reduction (out, width,
97650f4e 382 symbols[i]->tag,
17ee7397 383 reds->rules[j], false);
cd08e51e
AD
384 }
385 }
386 }
bc933ef1
AD
387
388 if (default_rule)
87675353 389 print_reduction (out, width,
8307162d 390 _("$default"), default_rule, true);
5092aba5
AD
391}
392
393
bc933ef1
AD
394/*--------------------------------------------------------------.
395| Report on OUT all the actions (shifts, gotos, reductions, and |
17ee7397 396| explicit erros from %nonassoc) of S. |
bc933ef1
AD
397`--------------------------------------------------------------*/
398
5092aba5 399static void
17ee7397 400print_actions (FILE *out, state *s)
5092aba5 401{
87675353 402 /* Print shifts. */
17ee7397
PE
403 print_transitions (s, out, true);
404 print_errs (out, s);
405 print_reductions (out, s);
87675353 406 /* Print gotos. */
17ee7397 407 print_transitions (s, out, false);
5092aba5
AD
408}
409
bc933ef1 410
17ee7397
PE
411/*----------------------------------.
412| Report all the data on S on OUT. |
413`----------------------------------*/
87675353 414
07a58c13 415static void
17ee7397 416print_state (FILE *out, state *s)
07a58c13 417{
342b8b6e 418 fputs ("\n\n", out);
17ee7397 419 fprintf (out, _("state %d"), s->number);
87675353 420 fputc ('\n', out);
17ee7397
PE
421 print_core (out, s);
422 print_actions (out, s);
423 if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
7ea9a33f
AD
424 {
425 fputc ('\n', out);
17ee7397 426 fputs (s->solved_conflicts, out);
7ea9a33f 427 }
07a58c13
AD
428}
429\f
430/*-----------------------------------------.
431| Print information on the whole grammar. |
432`-----------------------------------------*/
433
342b8b6e
AD
434#define END_TEST(End) \
435do { \
436 if (column + strlen(buffer) > (End)) \
437 { \
438 fprintf (out, "%s\n ", buffer); \
439 column = 3; \
440 buffer[0] = 0; \
441 } \
ff4423cc 442} while (0)
e06f0c34 443
07a58c13 444
4a120d45 445static void
342b8b6e 446print_grammar (FILE *out)
e06f0c34 447{
17ee7397 448 symbol_number i;
e06f0c34
RS
449 char buffer[90];
450 int column = 0;
451
6b98e4b5 452 grammar_rules_print (out);
e06f0c34
RS
453
454 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 455 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 456 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 457 if (token_translations[i] != undeftoken->number)
342b8b6e 458 {
97650f4e 459 const char *tag = symbols[token_translations[i]]->tag;
17ee7397
PE
460 rule_number r;
461 item_number *rhsp;
9222837b 462
342b8b6e 463 buffer[0] = 0;
6b98e4b5
AD
464 column = strlen (tag);
465 fputs (tag, out);
342b8b6e
AD
466 END_TEST (50);
467 sprintf (buffer, " (%d)", i);
e06f0c34 468
4b3d3a8e 469 for (r = 0; r < nrules; r++)
9222837b
AD
470 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
471 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
472 {
473 END_TEST (65);
4b3d3a8e 474 sprintf (buffer + strlen (buffer), " %d", r);
342b8b6e
AD
475 break;
476 }
477 fprintf (out, "%s\n", buffer);
478 }
d2d1b42b
AD
479 fputs ("\n\n", out);
480
342b8b6e 481
d2d1b42b 482 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 483 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
484 {
485 int left_count = 0, right_count = 0;
17ee7397 486 rule_number r;
97650f4e 487 const char *tag = symbols[i]->tag;
e06f0c34 488
4b3d3a8e 489 for (r = 0; r < nrules; r++)
e06f0c34 490 {
17ee7397 491 item_number *rhsp;
6b98e4b5 492 if (rules[r].lhs->number == i)
e06f0c34 493 left_count++;
9222837b
AD
494 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
495 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
496 {
497 right_count++;
498 break;
499 }
500 }
501
502 buffer[0] = 0;
6b98e4b5
AD
503 fputs (tag, out);
504 column = strlen (tag);
e06f0c34
RS
505 sprintf (buffer, " (%d)", i);
506 END_TEST (0);
507
508 if (left_count > 0)
509 {
510 END_TEST (50);
c29240e7 511 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 512
4b3d3a8e 513 for (r = 0; r < nrules; r++)
e06f0c34
RS
514 {
515 END_TEST (65);
6b98e4b5 516 if (rules[r].lhs->number == i)
4b3d3a8e 517 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
518 }
519 }
520
521 if (right_count > 0)
522 {
523 if (left_count > 0)
c29240e7 524 sprintf (buffer + strlen (buffer), ",");
e06f0c34 525 END_TEST (50);
c29240e7 526 sprintf (buffer + strlen (buffer), _(" on right:"));
4b3d3a8e 527 for (r = 0; r < nrules; r++)
e06f0c34 528 {
17ee7397 529 item_number *rhsp;
9222837b
AD
530 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
531 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
532 {
533 END_TEST (65);
4b3d3a8e 534 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
535 break;
536 }
537 }
538 }
342b8b6e 539 fprintf (out, "%s\n", buffer);
e06f0c34
RS
540 }
541}
07a58c13
AD
542\f
543void
544print_results (void)
545{
17ee7397 546 state_number i;
07a58c13 547
64d15509
AD
548 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
549 that conflicts with Posix. */
550 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 551
64d15509 552 reduce_output (out);
c8f002c7
AD
553 grammar_rules_partial_print (out,
554 _("Rules never reduced"), rule_never_reduced_p);
64d15509 555 conflicts_output (out);
342b8b6e 556
64d15509 557 print_grammar (out);
342b8b6e 558
ec3bc396
AD
559 /* If the whole state item sets, not only the kernels, are wanted,
560 `closure' will be run, which needs memory allocation/deallocation. */
561 if (report_flag & report_itemsets)
9e7f6bbd 562 new_closure (nritems);
5092aba5 563 /* Storage for print_reductions. */
34ba9743 564 shiftset = bitset_create (ntokens, BITSET_FIXED);
34ba9743 565 lookaheadset = bitset_create (ntokens, BITSET_FIXED);
64d15509 566 for (i = 0; i < nstates; i++)
29e88316 567 print_state (out, states[i]);
34ba9743
AD
568 bitset_free (shiftset);
569 bitset_free (lookaheadset);
ec3bc396 570 if (report_flag & report_itemsets)
64d15509
AD
571 free_closure ();
572
573 xfclose (out);
07a58c13 574}