]> git.saurik.com Git - bison.git/blame - src/print.c
Remove a dead item.
[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];
5fbb0954 127 token_number_t 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];
5fbb0954 169 token_number_t 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];
5fbb0954 193 token_number_t 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 362{
5fbb0954
AD
363 token_number_t i;
364 int j;
62a3e4f0 365 item_number_t *rule;
e06f0c34
RS
366 char buffer[90];
367 int column = 0;
368
369 /* rule # : LHS -> RHS */
d2d1b42b 370 fprintf (out, "%s\n\n", _("Grammar"));
b29b2ed5 371 fprintf (out, " %s\n", _("Number, Line, Rule"));
5fbb0954 372 for (j = 1; j < nrules + 1; j++)
c3b407f4
AD
373 {
374 fprintf (out, _(" %3d %3d %s ->"),
5fbb0954
AD
375 j - 1, rules[j].line, escape (rules[j].lhs->tag));
376 rule = rules[j].rhs;
c3b407f4
AD
377 if (*rule >= 0)
378 while (*rule >= 0)
379 fprintf (out, " %s", escape (symbols[*rule++]->tag));
380 else
381 fprintf (out, " /* %s */", _("empty"));
382 fputc ('\n', out);
383 }
d2d1b42b
AD
384 fputs ("\n\n", out);
385
e06f0c34
RS
386
387 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 388 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
18bcecb0 389 for (i = 0; i < max_user_token_number + 1; i++)
007a50a4 390 if (token_translations[i] != undeftoken->number)
342b8b6e
AD
391 {
392 buffer[0] = 0;
ad949da9
AD
393 column = strlen (escape (symbols[token_translations[i]]->tag));
394 fputs (escape (symbols[token_translations[i]]->tag), out);
342b8b6e
AD
395 END_TEST (50);
396 sprintf (buffer, " (%d)", i);
e06f0c34 397
18bcecb0 398 for (j = 1; j < nrules + 1; j++)
99013900 399 for (rule = rules[j].rhs; *rule >= 0; rule++)
5fbb0954 400 if (item_number_as_token_number (*rule) == token_translations[i])
342b8b6e
AD
401 {
402 END_TEST (65);
30171f79 403 sprintf (buffer + strlen (buffer), " %d", j - 1);
342b8b6e
AD
404 break;
405 }
406 fprintf (out, "%s\n", buffer);
407 }
d2d1b42b
AD
408 fputs ("\n\n", out);
409
342b8b6e 410
d2d1b42b 411 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
18bcecb0 412 for (i = ntokens; i < nsyms; i++)
e06f0c34
RS
413 {
414 int left_count = 0, right_count = 0;
415
18bcecb0 416 for (j = 1; j < nrules + 1; j++)
e06f0c34 417 {
bba97eb2 418 if (rules[j].lhs->number == i)
e06f0c34 419 left_count++;
99013900 420 for (rule = rules[j].rhs; *rule >= 0; rule++)
5fbb0954 421 if (item_number_as_token_number (*rule) == i)
e06f0c34
RS
422 {
423 right_count++;
424 break;
425 }
426 }
427
428 buffer[0] = 0;
ad949da9
AD
429 fputs (escape (symbols[i]->tag), out);
430 column = strlen (escape (symbols[i]->tag));
e06f0c34
RS
431 sprintf (buffer, " (%d)", i);
432 END_TEST (0);
433
434 if (left_count > 0)
435 {
436 END_TEST (50);
c29240e7 437 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34 438
18bcecb0 439 for (j = 1; j < nrules + 1; j++)
e06f0c34
RS
440 {
441 END_TEST (65);
bba97eb2 442 if (rules[j].lhs->number == i)
30171f79 443 sprintf (buffer + strlen (buffer), " %d", j - 1);
e06f0c34
RS
444 }
445 }
446
447 if (right_count > 0)
448 {
449 if (left_count > 0)
c29240e7 450 sprintf (buffer + strlen (buffer), ",");
e06f0c34 451 END_TEST (50);
c29240e7 452 sprintf (buffer + strlen (buffer), _(" on right:"));
18bcecb0 453 for (j = 1; j < nrules + 1; j++)
e06f0c34 454 {
99013900 455 for (rule = rules[j].rhs; *rule >= 0; rule++)
5fbb0954 456 if (item_number_as_token_number (*rule) == i)
e06f0c34
RS
457 {
458 END_TEST (65);
30171f79 459 sprintf (buffer + strlen (buffer), " %d", j - 1);
e06f0c34
RS
460 break;
461 }
462 }
463 }
342b8b6e 464 fprintf (out, "%s\n", buffer);
e06f0c34 465 }
d2d1b42b 466 fputs ("\n\n", out);
e06f0c34 467}
07a58c13
AD
468\f
469void
470print_results (void)
471{
602bbf31 472 size_t i;
07a58c13 473
64d15509
AD
474 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
475 that conflicts with Posix. */
476 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 477
64d15509
AD
478 size_t size = obstack_object_size (&output_obstack);
479 fwrite (obstack_finish (&output_obstack), 1, size, out);
480 obstack_free (&output_obstack, NULL);
07a58c13 481
64d15509
AD
482 if (size)
483 fputs ("\n\n", out);
342b8b6e 484
64d15509
AD
485 reduce_output (out);
486 conflicts_output (out);
342b8b6e 487
64d15509 488 print_grammar (out);
342b8b6e 489
5092aba5
AD
490 /* New experimental feature: output all the items of a state, not
491 only its kernel. Requires to run closure, which need memory
492 allocation/deallocation. */
64d15509 493 if (trace_flag)
9e7f6bbd 494 new_closure (nritems);
5092aba5 495 /* Storage for print_reductions. */
34ba9743 496 shiftset = bitset_create (ntokens, BITSET_FIXED);
34ba9743 497 lookaheadset = bitset_create (ntokens, BITSET_FIXED);
64d15509 498 for (i = 0; i < nstates; i++)
29e88316 499 print_state (out, states[i]);
34ba9743
AD
500 bitset_free (shiftset);
501 bitset_free (lookaheadset);
64d15509
AD
502 if (trace_flag)
503 free_closure ();
504
505 xfclose (out);
07a58c13 506}