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