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