]> git.saurik.com Git - bison.git/blame - src/print.c
Copy BYacc's nice way to report the grammar.
[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)
d4e7d3a1
AD
96 {
97 int j, k;
98 int nlookaheads = 0;
99 /* Look for lookaheads corresponding to this rule. */
100 for (j = 0; j < state->nlookaheads; ++j)
101 for (k = 0; k < ntokens; ++k)
102 if (bitset_test (LA[state->lookaheadsp + j], k)
103 && LArule[state->lookaheadsp + j]->number == rule)
104 nlookaheads++;
105 if (nlookaheads)
106 {
107 fprintf (out, " [");
108 for (j = 0; j < state->nlookaheads; ++j)
109 for (k = 0; k < ntokens; ++k)
110 if (bitset_test (LA[state->lookaheadsp + j], k)
111 && LArule[state->lookaheadsp + j]->number == rule)
112 fprintf (out, "%s%s",
6b98e4b5 113 symbol_tag_get (symbols[k]),
d4e7d3a1
AD
114 --nlookaheads ? ", " : "");
115 fprintf (out, "]");
116 }
117 }
118
30171f79 119 fprintf (out, _(" (rule %d)"), rule - 1);
43168960
AD
120 fputc ('\n', out);
121 }
e06f0c34 122
342b8b6e 123 fputc ('\n', out);
e06f0c34 124 }
e06f0c34
RS
125}
126
5092aba5 127
4a120d45 128static void
5092aba5 129print_shifts (FILE *out, state_t *state)
e06f0c34 130{
c29240e7 131 int i;
5092aba5 132 shifts *shiftp = state->shifts;
e06f0c34 133
2e729273 134 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
d954473d
AD
135 if (!SHIFT_IS_DISABLED (shiftp, i))
136 {
137 int state1 = shiftp->shifts[i];
a49aecd5 138 symbol_number_t symbol = states[state1]->accessing_symbol;
2e729273
AD
139 fprintf (out,
140 _(" %-4s\tshift, and go to state %d\n"),
6b98e4b5 141 symbol_tag_get (symbols[symbol]), state1);
d954473d 142 }
e06f0c34 143
d954473d
AD
144 if (i > 0)
145 fputc ('\n', out);
5092aba5 146}
e06f0c34 147
e06f0c34 148
5092aba5
AD
149static void
150print_errs (FILE *out, state_t *state)
151{
152 errs *errp = state->errs;
153 int i;
154
5092aba5
AD
155 for (i = 0; i < errp->nerrs; ++i)
156 if (errp->errs[i])
157 fprintf (out, _(" %-4s\terror (nonassociative)\n"),
6b98e4b5 158 symbol_tag_get (symbols[errp->errs[i]]));
5092aba5
AD
159
160 if (i > 0)
2cec70b9 161 fputc ('\n', out);
5092aba5 162}
e06f0c34 163
5092aba5
AD
164
165static void
166print_gotos (FILE *out, state_t *state)
167{
168 int i;
169 shifts *shiftp = state->shifts;
170
171 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
172 /* Skip token shifts. */;
e06f0c34 173
d954473d 174 if (i < shiftp->nshifts)
e06f0c34 175 {
d954473d
AD
176 for (; i < shiftp->nshifts; i++)
177 if (!SHIFT_IS_DISABLED (shiftp, i))
178 {
179 int state1 = shiftp->shifts[i];
a49aecd5 180 symbol_number_t symbol = states[state1]->accessing_symbol;
d954473d 181 fprintf (out, _(" %-4s\tgo to state %d\n"),
6b98e4b5 182 symbol_tag_get (symbols[symbol]), state1);
d954473d 183 }
e06f0c34 184
342b8b6e 185 fputc ('\n', out);
e06f0c34
RS
186 }
187}
188
5092aba5
AD
189static void
190print_reductions (FILE *out, state_t *state)
191{
192 int i;
193 shifts *shiftp = state->shifts;
194 reductions *redp = state->reductions;
195 errs *errp = state->errs;
196 int nodefault = 0;
197
80dac38c
AD
198 if (redp->nreds == 0)
199 return;
200
5092aba5
AD
201 if (state->consistent)
202 {
203 int rule = redp->rules[0];
a49aecd5 204 symbol_number_t symbol = rules[rule].lhs->number;
5092aba5 205 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
6b98e4b5 206 rule - 1, symbol_tag_get (symbols[symbol]));
5092aba5
AD
207 return;
208 }
209
34ba9743 210 bitset_zero (shiftset);
5092aba5
AD
211
212 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
213 if (!SHIFT_IS_DISABLED (shiftp, i))
214 {
215 /* if this state has a shift for the error token, don't use a
216 default rule. */
217 if (SHIFT_IS_ERROR (shiftp, i))
218 nodefault = 1;
34ba9743 219 bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
5092aba5
AD
220 }
221
2cec70b9
AD
222 for (i = 0; i < errp->nerrs; i++)
223 if (errp->errs[i])
34ba9743 224 bitset_set (shiftset, errp->errs[i]);
5092aba5
AD
225
226 if (state->nlookaheads == 1 && !nodefault)
227 {
b0299a2e 228 rule_t *default_rule = LArule[state->lookaheadsp];
5092aba5 229
f9abaa2c 230 bitset_and (lookaheadset, LA[state->lookaheadsp], shiftset);
5092aba5
AD
231
232 for (i = 0; i < ntokens; i++)
34ba9743 233 if (bitset_test (lookaheadset, i))
5092aba5 234 fprintf (out, _(" %-4s\t[reduce using rule %d (%s)]\n"),
6b98e4b5 235 symbol_tag_get (symbols[i]),
b0299a2e 236 default_rule->number - 1,
6b98e4b5 237 symbol_tag_get_n (default_rule->lhs, 1));
5092aba5
AD
238
239 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
b0299a2e 240 default_rule->number - 1,
6b98e4b5 241 symbol_tag_get (default_rule->lhs));
5092aba5
AD
242 }
243 else if (state->nlookaheads >= 1)
244 {
245 int cmax = 0;
246 int default_LA = -1;
b0299a2e 247 rule_t *default_rule = NULL;
5092aba5
AD
248
249 if (!nodefault)
250 for (i = 0; i < state->nlookaheads; ++i)
251 {
252 int count = 0;
f9abaa2c 253 int j;
5092aba5 254
f9abaa2c 255 bitset_andn (lookaheadset, LA[state->lookaheadsp + i], shiftset);
5092aba5
AD
256
257 for (j = 0; j < ntokens; j++)
34ba9743 258 if (bitset_test (lookaheadset, j))
5092aba5
AD
259 count++;
260
261 if (count > cmax)
262 {
263 cmax = count;
264 default_LA = state->lookaheadsp + i;
b0299a2e 265 default_rule = LArule[state->lookaheadsp + i];
5092aba5
AD
266 }
267
34ba9743 268 bitset_or (shiftset, shiftset, lookaheadset);
5092aba5
AD
269 }
270
34ba9743 271 bitset_zero (shiftset);
5092aba5
AD
272
273 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
274 if (!SHIFT_IS_DISABLED (shiftp, i))
34ba9743 275 bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
5092aba5
AD
276
277 for (i = 0; i < ntokens; i++)
278 {
279 int j;
280 int defaulted = 0;
34ba9743 281 int count = bitset_test (shiftset, i);
5092aba5
AD
282
283 for (j = 0; j < state->nlookaheads; ++j)
f9abaa2c
AD
284 if (bitset_test (LA[state->lookaheadsp + j], i))
285 {
286 if (count == 0)
287 {
288 if (state->lookaheadsp + j != default_LA)
5092aba5 289 fprintf (out,
f9abaa2c 290 _(" %-4s\treduce using rule %d (%s)\n"),
6b98e4b5 291 symbol_tag_get (symbols[i]),
b0299a2e 292 LArule[state->lookaheadsp + j]->number - 1,
6b98e4b5 293 symbol_tag_get_n (LArule[state->lookaheadsp + j]->lhs, 1));
f9abaa2c
AD
294 else
295 defaulted = 1;
296
297 count++;
298 }
299 else
300 {
301 if (defaulted)
302 fprintf (out,
303 _(" %-4s\treduce using rule %d (%s)\n"),
6b98e4b5 304 symbol_tag_get (symbols[i]),
b0299a2e 305 LArule[default_LA]->number - 1,
6b98e4b5 306 symbol_tag_get_n (LArule[default_LA]->lhs, 1));
f9abaa2c
AD
307 defaulted = 0;
308 fprintf (out,
309 _(" %-4s\t[reduce using rule %d (%s)]\n"),
6b98e4b5 310 symbol_tag_get (symbols[i]),
b0299a2e 311 LArule[state->lookaheadsp + j]->number - 1,
6b98e4b5 312 symbol_tag_get_n (LArule[state->lookaheadsp + j]->lhs, 1));
f9abaa2c
AD
313 }
314 }
5092aba5
AD
315 }
316
317 if (default_LA >= 0)
318 fprintf (out, _(" $default\treduce using rule %d (%s)\n"),
b0299a2e 319 default_rule->number - 1,
6b98e4b5 320 symbol_tag_get (default_rule->lhs));
5092aba5
AD
321 }
322}
323
324
325static void
326print_actions (FILE *out, state_t *state)
327{
328 reductions *redp = state->reductions;
329 shifts *shiftp = state->shifts;
330
80dac38c 331 if (shiftp->nshifts == 0 && redp->nreds == 0)
5092aba5
AD
332 {
333 if (final_state == state->number)
30171f79 334 fprintf (out, _(" $default\taccept\n"));
5092aba5 335 else
30171f79 336 fprintf (out, _(" NO ACTIONS\n"));
5092aba5
AD
337 return;
338 }
339
340 print_shifts (out, state);
341 print_errs (out, state);
80dac38c 342 print_reductions (out, state);
5092aba5
AD
343 print_gotos (out, state);
344}
345
07a58c13 346static void
065fbd27 347print_state (FILE *out, state_t *state)
07a58c13 348{
065fbd27 349 fprintf (out, _("state %d"), state->number);
342b8b6e
AD
350 fputs ("\n\n", out);
351 print_core (out, state);
352 print_actions (out, state);
b408954b
AD
353 if ((report_flag & report_solved_conflicts)
354 && state->solved_conflicts)
355 fputs (state->solved_conflicts, out);
d2d1b42b 356 fputs ("\n\n", out);
07a58c13
AD
357}
358\f
359/*-----------------------------------------.
360| Print information on the whole grammar. |
361`-----------------------------------------*/
362
342b8b6e
AD
363#define END_TEST(End) \
364do { \
365 if (column + strlen(buffer) > (End)) \
366 { \
367 fprintf (out, "%s\n ", buffer); \
368 column = 3; \
369 buffer[0] = 0; \
370 } \
ff4423cc 371} while (0)
e06f0c34 372
07a58c13 373
4a120d45 374static void
342b8b6e 375print_grammar (FILE *out)
e06f0c34 376{
a49aecd5 377 symbol_number_t i;
62a3e4f0 378 item_number_t *rule;
e06f0c34
RS
379 char buffer[90];
380 int column = 0;
381
6b98e4b5 382 grammar_rules_print (out);
e06f0c34
RS
383
384 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 385 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 386 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 387 if (token_translations[i] != undeftoken->number)
342b8b6e 388 {
6b98e4b5
AD
389 const char *tag = symbol_tag_get (symbols[token_translations[i]]);
390 int r;
342b8b6e 391 buffer[0] = 0;
6b98e4b5
AD
392 column = strlen (tag);
393 fputs (tag, out);
342b8b6e
AD
394 END_TEST (50);
395 sprintf (buffer, " (%d)", i);
e06f0c34 396
6b98e4b5
AD
397 for (r = 1; r < nrules + 1; r++)
398 for (rule = rules[r].rhs; *rule >= 0; rule++)
a49aecd5 399 if (item_number_as_symbol_number (*rule) == token_translations[i])
342b8b6e
AD
400 {
401 END_TEST (65);
6b98e4b5 402 sprintf (buffer + strlen (buffer), " %d", r - 1);
342b8b6e
AD
403 break;
404 }
405 fprintf (out, "%s\n", buffer);
406 }
d2d1b42b
AD
407 fputs ("\n\n", out);
408
342b8b6e 409
d2d1b42b 410 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 411 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
412 {
413 int left_count = 0, right_count = 0;
6b98e4b5
AD
414 int r;
415 const char *tag = symbol_tag_get (symbols[i]);
e06f0c34 416
6b98e4b5 417 for (r = 1; r < nrules + 1; r++)
e06f0c34 418 {
6b98e4b5 419 if (rules[r].lhs->number == i)
e06f0c34 420 left_count++;
6b98e4b5 421 for (rule = rules[r].rhs; *rule >= 0; rule++)
a49aecd5 422 if (item_number_as_symbol_number (*rule) == i)
e06f0c34
RS
423 {
424 right_count++;
425 break;
426 }
427 }
428
429 buffer[0] = 0;
6b98e4b5
AD
430 fputs (tag, out);
431 column = strlen (tag);
e06f0c34
RS
432 sprintf (buffer, " (%d)", i);
433 END_TEST (0);
434
435 if (left_count > 0)
436 {
437 END_TEST (50);
c29240e7 438 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 439
6b98e4b5 440 for (r = 1; r < nrules + 1; r++)
e06f0c34
RS
441 {
442 END_TEST (65);
6b98e4b5
AD
443 if (rules[r].lhs->number == i)
444 sprintf (buffer + strlen (buffer), " %d", r - 1);
e06f0c34
RS
445 }
446 }
447
448 if (right_count > 0)
449 {
450 if (left_count > 0)
c29240e7 451 sprintf (buffer + strlen (buffer), ",");
e06f0c34 452 END_TEST (50);
c29240e7 453 sprintf (buffer + strlen (buffer), _(" on right:"));
6b98e4b5 454 for (r = 1; r < nrules + 1; r++)
e06f0c34 455 {
6b98e4b5 456 for (rule = rules[r].rhs; *rule >= 0; rule++)
a49aecd5 457 if (item_number_as_symbol_number (*rule) == i)
e06f0c34
RS
458 {
459 END_TEST (65);
6b98e4b5 460 sprintf (buffer + strlen (buffer), " %d", r - 1);
e06f0c34
RS
461 break;
462 }
463 }
464 }
342b8b6e 465 fprintf (out, "%s\n", buffer);
e06f0c34 466 }
d2d1b42b 467 fputs ("\n\n", out);
e06f0c34 468}
07a58c13
AD
469\f
470void
471print_results (void)
472{
602bbf31 473 size_t i;
07a58c13 474
64d15509
AD
475 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
476 that conflicts with Posix. */
477 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 478
64d15509
AD
479 reduce_output (out);
480 conflicts_output (out);
342b8b6e 481
64d15509 482 print_grammar (out);
342b8b6e 483
ec3bc396
AD
484 /* If the whole state item sets, not only the kernels, are wanted,
485 `closure' will be run, which needs memory allocation/deallocation. */
486 if (report_flag & report_itemsets)
9e7f6bbd 487 new_closure (nritems);
5092aba5 488 /* Storage for print_reductions. */
34ba9743 489 shiftset = bitset_create (ntokens, BITSET_FIXED);
34ba9743 490 lookaheadset = bitset_create (ntokens, BITSET_FIXED);
64d15509 491 for (i = 0; i < nstates; i++)
29e88316 492 print_state (out, states[i]);
34ba9743
AD
493 bitset_free (shiftset);
494 bitset_free (lookaheadset);
ec3bc396 495 if (report_flag & report_itemsets)
64d15509
AD
496 free_closure ();
497
498 xfclose (out);
07a58c13 499}