]> git.saurik.com Git - bison.git/blame - src/print.c
* src/print.c (state_default_rule_compute): New, extracted from...
[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"
8adfa272 24#include "quotearg.h"
e06f0c34 25#include "files.h"
ad949da9 26#include "symtab.h"
e06f0c34 27#include "gram.h"
b2ca4022 28#include "LR0.h"
720d742f 29#include "lalr.h"
0619caf0 30#include "conflicts.h"
07a58c13
AD
31#include "getargs.h"
32#include "state.h"
b2ca4022 33#include "reader.h"
d7913476 34#include "print.h"
09b503c8 35#include "reduce.h"
43168960 36#include "closure.h"
34ba9743 37#include "bitset.h"
e06f0c34 38
34ba9743
AD
39static bitset shiftset;
40static bitset lookaheadset;
5092aba5 41
07a58c13 42#if 0
4a120d45 43static void
d2729d44 44print_token (int extnum, int token)
e06f0c34 45{
342b8b6e 46 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 47}
4a120d45 48#endif
e06f0c34 49
07a58c13 50\f
342b8b6e 51/*--------------------------------.
07a58c13 52| Report information on a state. |
342b8b6e 53`--------------------------------*/
e06f0c34 54
4a120d45 55static void
065fbd27 56print_core (FILE *out, state_t *state)
e06f0c34 57{
c29240e7 58 int i;
62a3e4f0 59 item_number_t *sitems = state->items;
5123689b 60 int snritems = state->nitems;
e06f0c34 61
ec3bc396
AD
62 /* Output all the items of a state, not only its kernel. */
63 if (report_flag & report_itemsets)
43168960 64 {
5123689b 65 closure (sitems, snritems);
43168960 66 sitems = itemset;
5123689b 67 snritems = nritemset;
43168960 68 }
e06f0c34 69
5123689b 70 if (snritems)
e06f0c34 71 {
5123689b 72 for (i = 0; i < snritems; i++)
43168960 73 {
62a3e4f0
AD
74 item_number_t *sp;
75 item_number_t *sp1;
43168960 76 int rule;
4bc30f78 77
43168960 78 sp1 = sp = ritem + sitems[i];
e06f0c34 79
75142d45 80 while (*sp >= 0)
43168960 81 sp++;
e06f0c34 82
43168960 83 rule = -(*sp);
6b98e4b5 84 fprintf (out, " %s -> ", symbol_tag_get (rules[rule].lhs));
e06f0c34 85
99013900 86 for (sp = rules[rule].rhs; sp < sp1; sp++)
6b98e4b5 87 fprintf (out, "%s ", symbol_tag_get (symbols[*sp]));
e06f0c34 88
43168960 89 fputc ('.', out);
e06f0c34 90
75142d45 91 for (/* Nothing */; *sp >= 0; ++sp)
6b98e4b5 92 fprintf (out, " %s", symbol_tag_get (symbols[*sp]));
43168960 93
ec3bc396
AD
94 /* Display the lookaheads? */
95 if (report_flag & report_lookaheads)
10e5b8bd 96 state_rule_lookaheads_print (state, &rules[rule], out);
d4e7d3a1 97
30171f79 98 fprintf (out, _(" (rule %d)"), rule - 1);
43168960
AD
99 fputc ('\n', out);
100 }
e06f0c34 101
342b8b6e 102 fputc ('\n', out);
e06f0c34 103 }
e06f0c34
RS
104}
105
5092aba5 106
4a120d45 107static void
5092aba5 108print_shifts (FILE *out, state_t *state)
e06f0c34 109{
c29240e7 110 int i;
32e1e0a4 111 shifts_t *shiftp = state->shifts;
e06f0c34 112
2e729273 113 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
d954473d
AD
114 if (!SHIFT_IS_DISABLED (shiftp, i))
115 {
d57650a5 116 state_number_t state1 = shiftp->shifts[i];
a49aecd5 117 symbol_number_t symbol = states[state1]->accessing_symbol;
2e729273
AD
118 fprintf (out,
119 _(" %-4s\tshift, and go to state %d\n"),
6b98e4b5 120 symbol_tag_get (symbols[symbol]), state1);
d954473d 121 }
e06f0c34 122
d954473d
AD
123 if (i > 0)
124 fputc ('\n', out);
5092aba5 125}
e06f0c34 126
e06f0c34 127
5092aba5
AD
128static void
129print_errs (FILE *out, state_t *state)
130{
8a731ca8 131 errs_t *errp = state->errs;
5092aba5
AD
132 int i;
133
5092aba5
AD
134 for (i = 0; i < errp->nerrs; ++i)
135 if (errp->errs[i])
136 fprintf (out, _(" %-4s\terror (nonassociative)\n"),
6b98e4b5 137 symbol_tag_get (symbols[errp->errs[i]]));
5092aba5
AD
138
139 if (i > 0)
2cec70b9 140 fputc ('\n', out);
5092aba5 141}
e06f0c34 142
5092aba5
AD
143
144static void
145print_gotos (FILE *out, state_t *state)
146{
147 int i;
32e1e0a4 148 shifts_t *shiftp = state->shifts;
5092aba5
AD
149
150 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
151 /* Skip token shifts. */;
e06f0c34 152
d954473d 153 if (i < shiftp->nshifts)
e06f0c34 154 {
d954473d
AD
155 for (; i < shiftp->nshifts; i++)
156 if (!SHIFT_IS_DISABLED (shiftp, i))
157 {
d57650a5 158 state_number_t state1 = shiftp->shifts[i];
a49aecd5 159 symbol_number_t symbol = states[state1]->accessing_symbol;
d954473d 160 fprintf (out, _(" %-4s\tgo to state %d\n"),
6b98e4b5 161 symbol_tag_get (symbols[symbol]), state1);
d954473d 162 }
e06f0c34 163
342b8b6e 164 fputc ('\n', out);
e06f0c34
RS
165 }
166}
167
bc933ef1
AD
168
169/*----------------------------------------------------------.
170| Return the default rule of this STATE if it has one, NULL |
171| otherwise. |
172`----------------------------------------------------------*/
173
174static rule_t *
175state_default_rule_compute (state_t *state)
176{
177 reductions_t *redp = state->reductions;
178 rule_t *default_rule = NULL;
179 int cmax = 0;
180 int i;
181
182 /* No need for a lookahead. */
183 if (state->consistent)
184 return &rules[redp->rules[0]];
185
186 /* 1. Each reduction is possibly masked by the lookaheads on which
187 we shift (S/R conflicts)... */
188 bitset_zero (shiftset);
189 {
190 shifts_t *shiftp = state->shifts;
191 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
192 if (!SHIFT_IS_DISABLED (shiftp, i))
193 {
194 /* If this state has a shift for the error token, don't use a
195 default rule. */
196 if (SHIFT_IS_ERROR (shiftp, i))
197 return NULL;
198 bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
199 }
200 }
201
202 /* 2. Each reduction is possibly masked by the lookaheads on which
203 we raise an error (due to %nonassoc). */
204 {
205 errs_t *errp = state->errs;
206 for (i = 0; i < errp->nerrs; i++)
207 if (errp->errs[i])
208 bitset_set (shiftset, errp->errs[i]);
209 }
210
211 for (i = 0; i < state->nlookaheads; ++i)
212 {
213 int count = 0;
214
215 /* How many non-masked lookaheads are there for this reduction?
216 */
217 bitset_andn (lookaheadset, state->lookaheads[i], shiftset);
218 count = bitset_count (lookaheadset);
219
220 if (count > cmax)
221 {
222 cmax = count;
223 default_rule = state->lookaheads_rule[i];
224 }
225
226 /* 3. And finally, each reduction is possibly masked by previous
227 reductions (in R/R conflicts, we keep the first reductions).
228 */
229 bitset_or (shiftset, shiftset, state->lookaheads[i]);
230 }
231
232 return default_rule;
233}
234
235
236/*----------------------------------------------------.
237| Report on OUT the reduction actions of this STATE. |
238`----------------------------------------------------*/
239
5092aba5
AD
240static void
241print_reductions (FILE *out, state_t *state)
242{
243 int i;
32e1e0a4 244 shifts_t *shiftp = state->shifts;
8a731ca8 245 reductions_t *redp = state->reductions;
bc933ef1 246 rule_t *default_rule = NULL;
5092aba5 247
80dac38c
AD
248 if (redp->nreds == 0)
249 return;
250
bc933ef1 251 default_rule = state_default_rule_compute (state);
5092aba5 252
34ba9743 253 bitset_zero (shiftset);
5092aba5
AD
254 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
255 if (!SHIFT_IS_DISABLED (shiftp, i))
bc933ef1 256 bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
5092aba5 257
bc933ef1 258 for (i = 0; i < ntokens; i++)
5092aba5 259 {
bc933ef1
AD
260 int j;
261 int defaulted = 0;
262 int count = bitset_test (shiftset, i);
5092aba5 263
bc933ef1
AD
264 for (j = 0; j < state->nlookaheads; ++j)
265 if (bitset_test (state->lookaheads[j], i))
5092aba5 266 {
bc933ef1 267 if (count == 0)
5092aba5 268 {
bc933ef1
AD
269 if (state->lookaheads_rule[j] != default_rule)
270 fprintf (out,
271 _(" %-4s\treduce using rule %d (%s)\n"),
272 symbol_tag_get (symbols[i]),
273 state->lookaheads_rule[j]->number - 1,
274 symbol_tag_get_n (state->lookaheads_rule[j]->lhs, 1));
275 else
276 defaulted = 1;
277 count++;
5092aba5 278 }
bc933ef1 279 else
f9abaa2c 280 {
bc933ef1
AD
281 if (defaulted)
282 fprintf (out,
283 _(" %-4s\treduce using rule %d (%s)\n"),
284 symbol_tag_get (symbols[i]),
285 default_rule->number - 1,
286 symbol_tag_get_n (default_rule->lhs, 1));
287 defaulted = 0;
288 fprintf (out,
289 _(" %-4s\t[reduce using rule %d (%s)]\n"),
290 symbol_tag_get (symbols[i]),
291 state->lookaheads_rule[j]->number - 1,
292 symbol_tag_get_n (state->lookaheads_rule[j]->lhs, 1));
f9abaa2c 293 }
bc933ef1 294 }
5092aba5 295 }
bc933ef1
AD
296
297 if (default_rule)
298 fprintf (out, _(" $default\treduce using rule %d (%s)\n"),
299 default_rule->number - 1,
300 symbol_tag_get (default_rule->lhs));
301 fputc ('\n', out);
5092aba5
AD
302}
303
304
bc933ef1
AD
305/*--------------------------------------------------------------.
306| Report on OUT all the actions (shifts, gotos, reductions, and |
307| explicit erros from %nonassoc) of STATE. |
308`--------------------------------------------------------------*/
309
5092aba5
AD
310static void
311print_actions (FILE *out, state_t *state)
312{
8a731ca8 313 reductions_t *redp = state->reductions;
32e1e0a4 314 shifts_t *shiftp = state->shifts;
5092aba5 315
80dac38c 316 if (shiftp->nshifts == 0 && redp->nreds == 0)
5092aba5 317 {
d57650a5 318 if (state->number == final_state->number)
bc933ef1 319 fprintf (out, _(" $default\taccept\n"));
5092aba5 320 else
bc933ef1 321 fprintf (out, _(" NO ACTIONS\n"));
5092aba5
AD
322 return;
323 }
324
325 print_shifts (out, state);
326 print_errs (out, state);
80dac38c 327 print_reductions (out, state);
5092aba5
AD
328 print_gotos (out, state);
329}
330
bc933ef1 331
07a58c13 332static void
065fbd27 333print_state (FILE *out, state_t *state)
07a58c13 334{
065fbd27 335 fprintf (out, _("state %d"), state->number);
342b8b6e
AD
336 fputs ("\n\n", out);
337 print_core (out, state);
338 print_actions (out, state);
b408954b
AD
339 if ((report_flag & report_solved_conflicts)
340 && state->solved_conflicts)
341 fputs (state->solved_conflicts, out);
d2d1b42b 342 fputs ("\n\n", out);
07a58c13
AD
343}
344\f
345/*-----------------------------------------.
346| Print information on the whole grammar. |
347`-----------------------------------------*/
348
342b8b6e
AD
349#define END_TEST(End) \
350do { \
351 if (column + strlen(buffer) > (End)) \
352 { \
353 fprintf (out, "%s\n ", buffer); \
354 column = 3; \
355 buffer[0] = 0; \
356 } \
ff4423cc 357} while (0)
e06f0c34 358
07a58c13 359
4a120d45 360static void
342b8b6e 361print_grammar (FILE *out)
e06f0c34 362{
a49aecd5 363 symbol_number_t i;
e06f0c34
RS
364 char buffer[90];
365 int column = 0;
366
6b98e4b5 367 grammar_rules_print (out);
e06f0c34
RS
368
369 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 370 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 371 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 372 if (token_translations[i] != undeftoken->number)
342b8b6e 373 {
6b98e4b5 374 const char *tag = symbol_tag_get (symbols[token_translations[i]]);
9222837b
AD
375 rule_number_t r;
376 item_number_t *rhsp;
377
342b8b6e 378 buffer[0] = 0;
6b98e4b5
AD
379 column = strlen (tag);
380 fputs (tag, out);
342b8b6e
AD
381 END_TEST (50);
382 sprintf (buffer, " (%d)", i);
e06f0c34 383
6b98e4b5 384 for (r = 1; r < nrules + 1; r++)
9222837b
AD
385 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
386 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
387 {
388 END_TEST (65);
6b98e4b5 389 sprintf (buffer + strlen (buffer), " %d", r - 1);
342b8b6e
AD
390 break;
391 }
392 fprintf (out, "%s\n", buffer);
393 }
d2d1b42b
AD
394 fputs ("\n\n", out);
395
342b8b6e 396
d2d1b42b 397 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 398 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
399 {
400 int left_count = 0, right_count = 0;
9222837b 401 rule_number_t r;
6b98e4b5 402 const char *tag = symbol_tag_get (symbols[i]);
e06f0c34 403
6b98e4b5 404 for (r = 1; r < nrules + 1; r++)
e06f0c34 405 {
9222837b 406 item_number_t *rhsp;
6b98e4b5 407 if (rules[r].lhs->number == i)
e06f0c34 408 left_count++;
9222837b
AD
409 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
410 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
411 {
412 right_count++;
413 break;
414 }
415 }
416
417 buffer[0] = 0;
6b98e4b5
AD
418 fputs (tag, out);
419 column = strlen (tag);
e06f0c34
RS
420 sprintf (buffer, " (%d)", i);
421 END_TEST (0);
422
423 if (left_count > 0)
424 {
425 END_TEST (50);
c29240e7 426 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 427
6b98e4b5 428 for (r = 1; r < nrules + 1; r++)
e06f0c34
RS
429 {
430 END_TEST (65);
6b98e4b5
AD
431 if (rules[r].lhs->number == i)
432 sprintf (buffer + strlen (buffer), " %d", r - 1);
e06f0c34
RS
433 }
434 }
435
436 if (right_count > 0)
437 {
438 if (left_count > 0)
c29240e7 439 sprintf (buffer + strlen (buffer), ",");
e06f0c34 440 END_TEST (50);
c29240e7 441 sprintf (buffer + strlen (buffer), _(" on right:"));
6b98e4b5 442 for (r = 1; r < nrules + 1; r++)
e06f0c34 443 {
9222837b
AD
444 item_number_t *rhsp;
445 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
446 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
447 {
448 END_TEST (65);
6b98e4b5 449 sprintf (buffer + strlen (buffer), " %d", r - 1);
e06f0c34
RS
450 break;
451 }
452 }
453 }
342b8b6e 454 fprintf (out, "%s\n", buffer);
e06f0c34 455 }
d2d1b42b 456 fputs ("\n\n", out);
e06f0c34 457}
07a58c13
AD
458\f
459void
460print_results (void)
461{
d57650a5 462 state_number_t i;
07a58c13 463
64d15509
AD
464 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
465 that conflicts with Posix. */
466 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 467
64d15509
AD
468 reduce_output (out);
469 conflicts_output (out);
342b8b6e 470
64d15509 471 print_grammar (out);
342b8b6e 472
ec3bc396
AD
473 /* If the whole state item sets, not only the kernels, are wanted,
474 `closure' will be run, which needs memory allocation/deallocation. */
475 if (report_flag & report_itemsets)
9e7f6bbd 476 new_closure (nritems);
5092aba5 477 /* Storage for print_reductions. */
34ba9743 478 shiftset = bitset_create (ntokens, BITSET_FIXED);
34ba9743 479 lookaheadset = bitset_create (ntokens, BITSET_FIXED);
64d15509 480 for (i = 0; i < nstates; i++)
29e88316 481 print_state (out, states[i]);
34ba9743
AD
482 bitset_free (shiftset);
483 bitset_free (lookaheadset);
ec3bc396 484 if (report_flag & report_itemsets)
64d15509
AD
485 free_closure ();
486
487 xfclose (out);
07a58c13 488}