]> git.saurik.com Git - bison.git/blame - src/print.c
* src/output.c (action_row): Let default_rule be always a rule
[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
5092aba5
AD
168static void
169print_reductions (FILE *out, state_t *state)
170{
171 int i;
32e1e0a4 172 shifts_t *shiftp = state->shifts;
8a731ca8
AD
173 reductions_t *redp = state->reductions;
174 errs_t *errp = state->errs;
5092aba5
AD
175 int nodefault = 0;
176
80dac38c
AD
177 if (redp->nreds == 0)
178 return;
179
5092aba5
AD
180 if (state->consistent)
181 {
182 int rule = redp->rules[0];
a49aecd5 183 symbol_number_t symbol = rules[rule].lhs->number;
5092aba5 184 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
6b98e4b5 185 rule - 1, symbol_tag_get (symbols[symbol]));
5092aba5
AD
186 return;
187 }
188
34ba9743 189 bitset_zero (shiftset);
5092aba5
AD
190
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 nodefault = 1;
34ba9743 198 bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
5092aba5
AD
199 }
200
2cec70b9
AD
201 for (i = 0; i < errp->nerrs; i++)
202 if (errp->errs[i])
34ba9743 203 bitset_set (shiftset, errp->errs[i]);
5092aba5
AD
204
205 if (state->nlookaheads == 1 && !nodefault)
206 {
c0263492 207 rule_t *default_rule = state->lookaheads_rule[0];
5092aba5 208
c0263492 209 bitset_and (lookaheadset, state->lookaheads[0], shiftset);
5092aba5 210
574fb2d5
AD
211 BITSET_EXECUTE (lookaheadset, 0, i,
212 {
213 fprintf (out, _(" %-4s\t[reduce using rule %d (%s)]\n"),
214 symbol_tag_get (symbols[i]),
215 default_rule->number - 1,
216 symbol_tag_get_n (default_rule->lhs, 1));
217 });
5092aba5 218 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
b0299a2e 219 default_rule->number - 1,
6b98e4b5 220 symbol_tag_get (default_rule->lhs));
5092aba5
AD
221 }
222 else if (state->nlookaheads >= 1)
223 {
224 int cmax = 0;
225 int default_LA = -1;
b0299a2e 226 rule_t *default_rule = NULL;
5092aba5
AD
227
228 if (!nodefault)
229 for (i = 0; i < state->nlookaheads; ++i)
230 {
231 int count = 0;
5092aba5 232
c0263492 233 bitset_andn (lookaheadset, state->lookaheads[i], shiftset);
574fb2d5 234 count = bitset_count (lookaheadset);
5092aba5
AD
235
236 if (count > cmax)
237 {
238 cmax = count;
c0263492
AD
239 default_LA = i;
240 default_rule = state->lookaheads_rule[i];
5092aba5
AD
241 }
242
34ba9743 243 bitset_or (shiftset, shiftset, lookaheadset);
5092aba5
AD
244 }
245
34ba9743 246 bitset_zero (shiftset);
5092aba5
AD
247
248 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
249 if (!SHIFT_IS_DISABLED (shiftp, i))
34ba9743 250 bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
5092aba5
AD
251
252 for (i = 0; i < ntokens; i++)
253 {
254 int j;
255 int defaulted = 0;
34ba9743 256 int count = bitset_test (shiftset, i);
5092aba5
AD
257
258 for (j = 0; j < state->nlookaheads; ++j)
c0263492 259 if (bitset_test (state->lookaheads[j], i))
f9abaa2c
AD
260 {
261 if (count == 0)
262 {
c0263492 263 if (j != default_LA)
5092aba5 264 fprintf (out,
f9abaa2c 265 _(" %-4s\treduce using rule %d (%s)\n"),
6b98e4b5 266 symbol_tag_get (symbols[i]),
c0263492
AD
267 state->lookaheads_rule[j]->number - 1,
268 symbol_tag_get_n (state->lookaheads_rule[j]->lhs, 1));
f9abaa2c
AD
269 else
270 defaulted = 1;
271
272 count++;
273 }
274 else
275 {
276 if (defaulted)
277 fprintf (out,
278 _(" %-4s\treduce using rule %d (%s)\n"),
6b98e4b5 279 symbol_tag_get (symbols[i]),
c0263492
AD
280 state->lookaheads_rule[default_LA]->number - 1,
281 symbol_tag_get_n (state->lookaheads_rule[default_LA]->lhs, 1));
f9abaa2c
AD
282 defaulted = 0;
283 fprintf (out,
284 _(" %-4s\t[reduce using rule %d (%s)]\n"),
6b98e4b5 285 symbol_tag_get (symbols[i]),
c0263492
AD
286 state->lookaheads_rule[j]->number - 1,
287 symbol_tag_get_n (state->lookaheads_rule[j]->lhs, 1));
f9abaa2c
AD
288 }
289 }
5092aba5
AD
290 }
291
292 if (default_LA >= 0)
293 fprintf (out, _(" $default\treduce using rule %d (%s)\n"),
b0299a2e 294 default_rule->number - 1,
6b98e4b5 295 symbol_tag_get (default_rule->lhs));
5092aba5
AD
296 }
297}
298
299
300static void
301print_actions (FILE *out, state_t *state)
302{
8a731ca8 303 reductions_t *redp = state->reductions;
32e1e0a4 304 shifts_t *shiftp = state->shifts;
5092aba5 305
80dac38c 306 if (shiftp->nshifts == 0 && redp->nreds == 0)
5092aba5 307 {
d57650a5 308 if (state->number == final_state->number)
30171f79 309 fprintf (out, _(" $default\taccept\n"));
5092aba5 310 else
30171f79 311 fprintf (out, _(" NO ACTIONS\n"));
5092aba5
AD
312 return;
313 }
314
315 print_shifts (out, state);
316 print_errs (out, state);
80dac38c 317 print_reductions (out, state);
5092aba5
AD
318 print_gotos (out, state);
319}
320
07a58c13 321static void
065fbd27 322print_state (FILE *out, state_t *state)
07a58c13 323{
065fbd27 324 fprintf (out, _("state %d"), state->number);
342b8b6e
AD
325 fputs ("\n\n", out);
326 print_core (out, state);
327 print_actions (out, state);
b408954b
AD
328 if ((report_flag & report_solved_conflicts)
329 && state->solved_conflicts)
330 fputs (state->solved_conflicts, out);
d2d1b42b 331 fputs ("\n\n", out);
07a58c13
AD
332}
333\f
334/*-----------------------------------------.
335| Print information on the whole grammar. |
336`-----------------------------------------*/
337
342b8b6e
AD
338#define END_TEST(End) \
339do { \
340 if (column + strlen(buffer) > (End)) \
341 { \
342 fprintf (out, "%s\n ", buffer); \
343 column = 3; \
344 buffer[0] = 0; \
345 } \
ff4423cc 346} while (0)
e06f0c34 347
07a58c13 348
4a120d45 349static void
342b8b6e 350print_grammar (FILE *out)
e06f0c34 351{
a49aecd5 352 symbol_number_t i;
e06f0c34
RS
353 char buffer[90];
354 int column = 0;
355
6b98e4b5 356 grammar_rules_print (out);
e06f0c34
RS
357
358 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 359 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 360 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 361 if (token_translations[i] != undeftoken->number)
342b8b6e 362 {
6b98e4b5 363 const char *tag = symbol_tag_get (symbols[token_translations[i]]);
9222837b
AD
364 rule_number_t r;
365 item_number_t *rhsp;
366
342b8b6e 367 buffer[0] = 0;
6b98e4b5
AD
368 column = strlen (tag);
369 fputs (tag, out);
342b8b6e
AD
370 END_TEST (50);
371 sprintf (buffer, " (%d)", i);
e06f0c34 372
6b98e4b5 373 for (r = 1; r < nrules + 1; r++)
9222837b
AD
374 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
375 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
342b8b6e
AD
376 {
377 END_TEST (65);
6b98e4b5 378 sprintf (buffer + strlen (buffer), " %d", r - 1);
342b8b6e
AD
379 break;
380 }
381 fprintf (out, "%s\n", buffer);
382 }
d2d1b42b
AD
383 fputs ("\n\n", out);
384
342b8b6e 385
d2d1b42b 386 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 387 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
388 {
389 int left_count = 0, right_count = 0;
9222837b 390 rule_number_t r;
6b98e4b5 391 const char *tag = symbol_tag_get (symbols[i]);
e06f0c34 392
6b98e4b5 393 for (r = 1; r < nrules + 1; r++)
e06f0c34 394 {
9222837b 395 item_number_t *rhsp;
6b98e4b5 396 if (rules[r].lhs->number == i)
e06f0c34 397 left_count++;
9222837b
AD
398 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
399 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
400 {
401 right_count++;
402 break;
403 }
404 }
405
406 buffer[0] = 0;
6b98e4b5
AD
407 fputs (tag, out);
408 column = strlen (tag);
e06f0c34
RS
409 sprintf (buffer, " (%d)", i);
410 END_TEST (0);
411
412 if (left_count > 0)
413 {
414 END_TEST (50);
c29240e7 415 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 416
6b98e4b5 417 for (r = 1; r < nrules + 1; r++)
e06f0c34
RS
418 {
419 END_TEST (65);
6b98e4b5
AD
420 if (rules[r].lhs->number == i)
421 sprintf (buffer + strlen (buffer), " %d", r - 1);
e06f0c34
RS
422 }
423 }
424
425 if (right_count > 0)
426 {
427 if (left_count > 0)
c29240e7 428 sprintf (buffer + strlen (buffer), ",");
e06f0c34 429 END_TEST (50);
c29240e7 430 sprintf (buffer + strlen (buffer), _(" on right:"));
6b98e4b5 431 for (r = 1; r < nrules + 1; r++)
e06f0c34 432 {
9222837b
AD
433 item_number_t *rhsp;
434 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
435 if (item_number_as_symbol_number (*rhsp) == i)
e06f0c34
RS
436 {
437 END_TEST (65);
6b98e4b5 438 sprintf (buffer + strlen (buffer), " %d", r - 1);
e06f0c34
RS
439 break;
440 }
441 }
442 }
342b8b6e 443 fprintf (out, "%s\n", buffer);
e06f0c34 444 }
d2d1b42b 445 fputs ("\n\n", out);
e06f0c34 446}
07a58c13
AD
447\f
448void
449print_results (void)
450{
d57650a5 451 state_number_t i;
07a58c13 452
64d15509
AD
453 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
454 that conflicts with Posix. */
455 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 456
64d15509
AD
457 reduce_output (out);
458 conflicts_output (out);
342b8b6e 459
64d15509 460 print_grammar (out);
342b8b6e 461
ec3bc396
AD
462 /* If the whole state item sets, not only the kernels, are wanted,
463 `closure' will be run, which needs memory allocation/deallocation. */
464 if (report_flag & report_itemsets)
9e7f6bbd 465 new_closure (nritems);
5092aba5 466 /* Storage for print_reductions. */
34ba9743 467 shiftset = bitset_create (ntokens, BITSET_FIXED);
34ba9743 468 lookaheadset = bitset_create (ntokens, BITSET_FIXED);
64d15509 469 for (i = 0; i < nstates; i++)
29e88316 470 print_state (out, states[i]);
34ba9743
AD
471 bitset_free (shiftset);
472 bitset_free (lookaheadset);
ec3bc396 473 if (report_flag & report_itemsets)
64d15509
AD
474 free_closure ();
475
476 xfclose (out);
07a58c13 477}