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