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