]> git.saurik.com Git - bison.git/blame - src/print.c
Minor code cleanup in parser table construction.
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
a737b216 2
2cec9080 3 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005
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
8dd162d3 43static bitset shift_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
8dd162d3 255 bitset_zero (shift_set);
17ee7397 256 FOR_EACH_SHIFT (trans, i)
8dd162d3 257 bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
5092aba5 258
742e4900 259 /* Compute the width of the lookahead token column. */
87675353
AD
260 if (default_rule)
261 width = strlen (_("$default"));
cd08e51e 262
742e4900 263 if (reds->lookahead_tokens)
cd08e51e
AD
264 for (i = 0; i < ntokens; i++)
265 {
8dd162d3 266 bool count = bitset_test (shift_set, i);
cd08e51e 267
17ee7397 268 for (j = 0; j < reds->num; ++j)
742e4900 269 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 270 {
d0829076 271 if (! count)
cd08e51e 272 {
17ee7397 273 if (reds->rules[j] != default_rule)
cd08e51e 274 max_length (&width, symbols[i]->tag);
d0829076 275 count = true;
cd08e51e
AD
276 }
277 else
278 {
97650f4e 279 max_length (&width, symbols[i]->tag);
cd08e51e
AD
280 }
281 }
282 }
87675353
AD
283
284 /* Nothing to report. */
285 if (!width)
286 return;
287
288 fputc ('\n', out);
289 width += 2;
290
742e4900
JD
291 /* Report lookahead tokens (or $default) and reductions. */
292 if (reds->lookahead_tokens)
cd08e51e
AD
293 for (i = 0; i < ntokens; i++)
294 {
d0829076 295 bool defaulted = false;
8dd162d3 296 bool count = bitset_test (shift_set, i);
cd08e51e 297
17ee7397 298 for (j = 0; j < reds->num; ++j)
742e4900 299 if (bitset_test (reds->lookahead_tokens[j], i))
cd08e51e 300 {
d0829076 301 if (! count)
cd08e51e 302 {
17ee7397 303 if (reds->rules[j] != default_rule)
cd08e51e
AD
304 print_reduction (out, width,
305 symbols[i]->tag,
17ee7397 306 reds->rules[j], true);
cd08e51e 307 else
d0829076
PE
308 defaulted = true;
309 count = true;
cd08e51e
AD
310 }
311 else
312 {
313 if (defaulted)
314 print_reduction (out, width,
315 symbols[i]->tag,
8307162d 316 default_rule, true);
d0829076 317 defaulted = false;
87675353 318 print_reduction (out, width,
97650f4e 319 symbols[i]->tag,
17ee7397 320 reds->rules[j], false);
cd08e51e
AD
321 }
322 }
323 }
bc933ef1
AD
324
325 if (default_rule)
87675353 326 print_reduction (out, width,
8307162d 327 _("$default"), default_rule, true);
5092aba5
AD
328}
329
330
bc933ef1
AD
331/*--------------------------------------------------------------.
332| Report on OUT all the actions (shifts, gotos, reductions, and |
17ee7397 333| explicit erros from %nonassoc) of S. |
bc933ef1
AD
334`--------------------------------------------------------------*/
335
5092aba5 336static void
17ee7397 337print_actions (FILE *out, state *s)
5092aba5 338{
87675353 339 /* Print shifts. */
17ee7397
PE
340 print_transitions (s, out, true);
341 print_errs (out, s);
342 print_reductions (out, s);
87675353 343 /* Print gotos. */
17ee7397 344 print_transitions (s, out, false);
5092aba5
AD
345}
346
bc933ef1 347
17ee7397
PE
348/*----------------------------------.
349| Report all the data on S on OUT. |
350`----------------------------------*/
87675353 351
07a58c13 352static void
17ee7397 353print_state (FILE *out, state *s)
07a58c13 354{
342b8b6e 355 fputs ("\n\n", out);
17ee7397 356 fprintf (out, _("state %d"), s->number);
87675353 357 fputc ('\n', out);
17ee7397
PE
358 print_core (out, s);
359 print_actions (out, s);
360 if ((report_flag & report_solved_conflicts) && s->solved_conflicts)
7ea9a33f
AD
361 {
362 fputc ('\n', out);
17ee7397 363 fputs (s->solved_conflicts, out);
7ea9a33f 364 }
07a58c13
AD
365}
366\f
367/*-----------------------------------------.
368| Print information on the whole grammar. |
369`-----------------------------------------*/
370
342b8b6e
AD
371#define END_TEST(End) \
372do { \
373 if (column + strlen(buffer) > (End)) \
374 { \
375 fprintf (out, "%s\n ", buffer); \
376 column = 3; \
377 buffer[0] = 0; \
378 } \
ff4423cc 379} while (0)
e06f0c34 380
07a58c13 381
4a120d45 382static void
342b8b6e 383print_grammar (FILE *out)
e06f0c34 384{
17ee7397 385 symbol_number i;
e06f0c34
RS
386 char buffer[90];
387 int column = 0;
388
6b98e4b5 389 grammar_rules_print (out);
e06f0c34
RS
390
391 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 392 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 393 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 394 if (token_translations[i] != undeftoken->number)
342b8b6e 395 {
97650f4e 396 const char *tag = symbols[token_translations[i]]->tag;
17ee7397
PE
397 rule_number r;
398 item_number *rhsp;
9222837b 399
342b8b6e 400 buffer[0] = 0;
6b98e4b5
AD
401 column = strlen (tag);
402 fputs (tag, out);
342b8b6e
AD
403 END_TEST (50);
404 sprintf (buffer, " (%d)", i);
e06f0c34 405
4b3d3a8e 406 for (r = 0; r < nrules; r++)
9222837b
AD
407 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
408 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
409 {
410 END_TEST (65);
4b3d3a8e 411 sprintf (buffer + strlen (buffer), " %d", r);
342b8b6e
AD
412 break;
413 }
414 fprintf (out, "%s\n", buffer);
415 }
d2d1b42b
AD
416 fputs ("\n\n", out);
417
342b8b6e 418
d2d1b42b 419 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 420 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
421 {
422 int left_count = 0, right_count = 0;
17ee7397 423 rule_number r;
97650f4e 424 const char *tag = symbols[i]->tag;
e06f0c34 425
4b3d3a8e 426 for (r = 0; r < nrules; r++)
e06f0c34 427 {
17ee7397 428 item_number *rhsp;
6b98e4b5 429 if (rules[r].lhs->number == i)
e06f0c34 430 left_count++;
9222837b
AD
431 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
432 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
433 {
434 right_count++;
435 break;
436 }
437 }
438
439 buffer[0] = 0;
6b98e4b5
AD
440 fputs (tag, out);
441 column = strlen (tag);
e06f0c34
RS
442 sprintf (buffer, " (%d)", i);
443 END_TEST (0);
444
445 if (left_count > 0)
446 {
447 END_TEST (50);
c29240e7 448 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 449
4b3d3a8e 450 for (r = 0; r < nrules; r++)
e06f0c34
RS
451 {
452 END_TEST (65);
6b98e4b5 453 if (rules[r].lhs->number == i)
4b3d3a8e 454 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
455 }
456 }
457
458 if (right_count > 0)
459 {
460 if (left_count > 0)
c29240e7 461 sprintf (buffer + strlen (buffer), ",");
e06f0c34 462 END_TEST (50);
c29240e7 463 sprintf (buffer + strlen (buffer), _(" on right:"));
4b3d3a8e 464 for (r = 0; r < nrules; r++)
e06f0c34 465 {
17ee7397 466 item_number *rhsp;
9222837b
AD
467 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
468 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
469 {
470 END_TEST (65);
4b3d3a8e 471 sprintf (buffer + strlen (buffer), " %d", r);
e06f0c34
RS
472 break;
473 }
474 }
475 }
342b8b6e 476 fprintf (out, "%s\n", buffer);
e06f0c34
RS
477 }
478}
07a58c13
AD
479\f
480void
481print_results (void)
482{
17ee7397 483 state_number i;
07a58c13 484
64d15509
AD
485 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
486 that conflicts with Posix. */
487 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 488
64d15509 489 reduce_output (out);
c8f002c7
AD
490 grammar_rules_partial_print (out,
491 _("Rules never reduced"), rule_never_reduced_p);
64d15509 492 conflicts_output (out);
342b8b6e 493
64d15509 494 print_grammar (out);
342b8b6e 495
ec3bc396
AD
496 /* If the whole state item sets, not only the kernels, are wanted,
497 `closure' will be run, which needs memory allocation/deallocation. */
498 if (report_flag & report_itemsets)
9e7f6bbd 499 new_closure (nritems);
5092aba5 500 /* Storage for print_reductions. */
8dd162d3 501 shift_set = bitset_create (ntokens, BITSET_FIXED);
64d15509 502 for (i = 0; i < nstates; i++)
29e88316 503 print_state (out, states[i]);
8dd162d3 504 bitset_free (shift_set);
ec3bc396 505 if (report_flag & report_itemsets)
64d15509
AD
506 free_closure ();
507
508 xfclose (out);
07a58c13 509}