]> git.saurik.com Git - bison.git/blob - src/print.c
7adb51b06016495469461e2b4b49e3a9cf1d894f
[bison.git] / src / print.c
1 /* Print information on generated parser, for bison,
2 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
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.
11
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.
16
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. */
21
22
23 #include "system.h"
24 #include "quotearg.h"
25 #include "files.h"
26 #include "symtab.h"
27 #include "gram.h"
28 #include "LR0.h"
29 #include "lalr.h"
30 #include "conflicts.h"
31 #include "getargs.h"
32 #include "state.h"
33 #include "reader.h"
34 #include "print.h"
35 #include "reduce.h"
36 #include "closure.h"
37 #include "bitset.h"
38
39 static bitset shiftset;
40 static bitset lookaheadset;
41
42 #if 0
43 static void
44 print_token (int extnum, int token)
45 {
46 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
47 }
48 #endif
49
50 \f
51
52 /*---------------------------------------.
53 | *WIDTH := max (*WIDTH, strlen (STR)). |
54 `---------------------------------------*/
55
56 static void
57 max_length (size_t *width, const char *str)
58 {
59 size_t len = strlen (str);
60 if (len > *width)
61 *width = len;
62 }
63
64 /*--------------------------------.
65 | Report information on a state. |
66 `--------------------------------*/
67
68 static void
69 print_core (FILE *out, state_t *state)
70 {
71 int i;
72 item_number_t *sitems = state->items;
73 int snritems = state->nitems;
74 symbol_t *previous_lhs = NULL;
75
76 /* Output all the items of a state, not only its kernel. */
77 if (report_flag & report_itemsets)
78 {
79 closure (sitems, snritems);
80 sitems = itemset;
81 snritems = nritemset;
82 }
83
84 if (!snritems)
85 return;
86
87 fputc ('\n', out);
88
89 for (i = 0; i < snritems; i++)
90 {
91 item_number_t *sp;
92 item_number_t *sp1;
93 int rule;
94
95 sp1 = sp = ritem + sitems[i];
96
97 while (*sp >= 0)
98 sp++;
99
100 rule = -(*sp);
101
102 rule_lhs_print (&rules[rule], previous_lhs, out);
103 previous_lhs = rules[rule].lhs;
104
105 for (sp = rules[rule].rhs; sp < sp1; sp++)
106 fprintf (out, " %s", symbols[*sp]->tag);
107 fputs (" .", out);
108 for (/* Nothing */; *sp >= 0; ++sp)
109 fprintf (out, " %s", symbols[*sp]->tag);
110
111 /* Display the lookaheads? */
112 if (report_flag & report_lookaheads)
113 state_rule_lookaheads_print (state, &rules[rule], out);
114
115 fputc ('\n', out);
116 }
117 }
118
119
120 /*----------------------------------------------------------------.
121 | Report the shifts iff DISPLAY_SHIFTS_P or the gotos of STATE on |
122 | OUT. |
123 `----------------------------------------------------------------*/
124
125 static void
126 print_transitions (state_t *state, FILE *out, bool display_transitions_p)
127 {
128 transitions_t *transitions = state->transitions;
129 size_t width = 0;
130 int i;
131
132 /* Compute the width of the lookaheads column. */
133 for (i = 0; i < transitions->num; i++)
134 if (!TRANSITION_IS_DISABLED (transitions, i)
135 && TRANSITION_IS_SHIFT (transitions, i) == display_transitions_p)
136 {
137 symbol_t *symbol = symbols[TRANSITION_SYMBOL (transitions, i)];
138 max_length (&width, symbol->tag);
139 }
140
141 /* Nothing to report. */
142 if (!width)
143 return;
144
145 fputc ('\n', out);
146 width += 2;
147
148 /* Report lookaheads and shifts. */
149 for (i = 0; i < transitions->num; i++)
150 if (!TRANSITION_IS_DISABLED (transitions, i)
151 && TRANSITION_IS_SHIFT (transitions, i) == display_transitions_p)
152 {
153 symbol_t *symbol = symbols[TRANSITION_SYMBOL (transitions, i)];
154 const char *tag = symbol->tag;
155 state_number_t state1 = transitions->states[i];
156 int j;
157
158 fprintf (out, " %s", tag);
159 for (j = width - strlen (tag); j > 0; --j)
160 fputc (' ', out);
161 if (display_transitions_p)
162 fprintf (out, _("shift, and go to state %d\n"), state1);
163 else
164 fprintf (out, _("go to state %d\n"), state1);
165 }
166 }
167
168
169 /*------------------------------------------------------------.
170 | Report the explicit errors of STATE raised from %nonassoc. |
171 `------------------------------------------------------------*/
172
173 static void
174 print_errs (FILE *out, state_t *state)
175 {
176 errs_t *errp = state->errs;
177 size_t width = 0;
178 int i;
179
180 /* Compute the width of the lookaheads column. */
181 for (i = 0; i < errp->num; ++i)
182 if (errp->symbols[i])
183 max_length (&width, symbols[errp->symbols[i]]->tag);
184
185 /* Nothing to report. */
186 if (!width)
187 return;
188
189 fputc ('\n', out);
190 width += 2;
191
192 /* Report lookaheads and errors. */
193 for (i = 0; i < errp->num; ++i)
194 if (errp->symbols[i])
195 {
196 const char *tag = symbols[errp->symbols[i]]->tag;
197 int j;
198 fprintf (out, " %s", tag);
199 for (j = width - strlen (tag); j > 0; --j)
200 fputc (' ', out);
201 fputs (_("error (nonassociative)\n"), out);
202 }
203 }
204
205
206 /*----------------------------------------------------------.
207 | Return the default rule of this STATE if it has one, NULL |
208 | otherwise. |
209 `----------------------------------------------------------*/
210
211 static rule_t *
212 state_default_rule (state_t *state)
213 {
214 reductions_t *redp = state->reductions;
215 rule_t *default_rule = NULL;
216 int cmax = 0;
217 int i;
218
219 /* No need for a lookahead. */
220 if (state->consistent)
221 return &rules[redp->rules[0]];
222
223 /* 1. Each reduction is possibly masked by the lookaheads on which
224 we shift (S/R conflicts)... */
225 bitset_zero (shiftset);
226 {
227 transitions_t *transitions = state->transitions;
228 for (i = 0; i < transitions->num && TRANSITION_IS_SHIFT (transitions, i); i++)
229 if (!TRANSITION_IS_DISABLED (transitions, i))
230 {
231 /* If this state has a shift for the error token, don't use a
232 default rule. */
233 if (TRANSITION_IS_ERROR (transitions, i))
234 return NULL;
235 bitset_set (shiftset, TRANSITION_SYMBOL (transitions, i));
236 }
237 }
238
239 /* 2. Each reduction is possibly masked by the lookaheads on which
240 we raise an error (due to %nonassoc). */
241 {
242 errs_t *errp = state->errs;
243 for (i = 0; i < errp->num; i++)
244 if (errp->symbols[i])
245 bitset_set (shiftset, errp->symbols[i]);
246 }
247
248 for (i = 0; i < state->nlookaheads; ++i)
249 {
250 int count = 0;
251
252 /* How many non-masked lookaheads are there for this reduction?
253 */
254 bitset_andn (lookaheadset, state->lookaheads[i], shiftset);
255 count = bitset_count (lookaheadset);
256
257 if (count > cmax)
258 {
259 cmax = count;
260 default_rule = state->lookaheads_rule[i];
261 }
262
263 /* 3. And finally, each reduction is possibly masked by previous
264 reductions (in R/R conflicts, we keep the first reductions).
265 */
266 bitset_or (shiftset, shiftset, state->lookaheads[i]);
267 }
268
269 return default_rule;
270 }
271
272
273 /*--------------------------------------------------------------------.
274 | Report a reduction of RULE on LOOKAHEADS (which can be `default'). |
275 | If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
276 | R/R conflicts). |
277 `--------------------------------------------------------------------*/
278
279 static void
280 print_reduction (FILE *out, size_t width,
281 const char *lookahead,
282 rule_t *rule, bool enabled)
283 {
284 int j;
285 fprintf (out, " %s", lookahead);
286 for (j = width - strlen (lookahead); j > 0; --j)
287 fputc (' ', out);
288 if (!enabled)
289 fputc ('[', out);
290 fprintf (out, _("reduce using rule %d (%s)"),
291 rule->number - 1, rule->lhs->tag);
292 if (!enabled)
293 fputc (']', out);
294 fputc ('\n', out);
295 }
296
297
298 /*----------------------------------------------------.
299 | Report on OUT the reduction actions of this STATE. |
300 `----------------------------------------------------*/
301
302 static void
303 print_reductions (FILE *out, state_t *state)
304 {
305 transitions_t *transitions = state->transitions;
306 reductions_t *redp = state->reductions;
307 rule_t *default_rule = NULL;
308 size_t width = 0;
309 int i, j;
310
311 if (redp->num == 0)
312 return;
313
314 default_rule = state_default_rule (state);
315
316 bitset_zero (shiftset);
317 for (i = 0; i < transitions->num && TRANSITION_IS_SHIFT (transitions, i); i++)
318 if (!TRANSITION_IS_DISABLED (transitions, i))
319 bitset_set (shiftset, TRANSITION_SYMBOL (transitions, i));
320
321 /* Compute the width of the lookaheads column. */
322 if (default_rule)
323 width = strlen (_("$default"));
324 for (i = 0; i < ntokens; i++)
325 {
326 int count = bitset_test (shiftset, i);
327
328 for (j = 0; j < state->nlookaheads; ++j)
329 if (bitset_test (state->lookaheads[j], i))
330 {
331 if (count == 0)
332 {
333 if (state->lookaheads_rule[j] != default_rule)
334 max_length (&width, symbols[i]->tag);
335 count++;
336 }
337 else
338 {
339 max_length (&width, symbols[i]->tag);
340 }
341 }
342 }
343
344 /* Nothing to report. */
345 if (!width)
346 return;
347
348 fputc ('\n', out);
349 width += 2;
350
351 /* Report lookaheads (or $default) and reductions. */
352 for (i = 0; i < ntokens; i++)
353 {
354 int defaulted = 0;
355 int count = bitset_test (shiftset, i);
356
357 for (j = 0; j < state->nlookaheads; ++j)
358 if (bitset_test (state->lookaheads[j], i))
359 {
360 if (count == 0)
361 {
362 if (state->lookaheads_rule[j] != default_rule)
363 print_reduction (out, width,
364 symbols[i]->tag,
365 state->lookaheads_rule[j], TRUE);
366 else
367 defaulted = 1;
368 count++;
369 }
370 else
371 {
372 if (defaulted)
373 print_reduction (out, width,
374 symbols[i]->tag,
375 default_rule, TRUE);
376 defaulted = 0;
377 print_reduction (out, width,
378 symbols[i]->tag,
379 state->lookaheads_rule[j], FALSE);
380 }
381 }
382 }
383
384 if (default_rule)
385 print_reduction (out, width,
386 _("$default"), default_rule, TRUE);
387 }
388
389
390 /*--------------------------------------------------------------.
391 | Report on OUT all the actions (shifts, gotos, reductions, and |
392 | explicit erros from %nonassoc) of STATE. |
393 `--------------------------------------------------------------*/
394
395 static void
396 print_actions (FILE *out, state_t *state)
397 {
398 reductions_t *redp = state->reductions;
399 transitions_t *transitions = state->transitions;
400
401 if (transitions->num == 0 && redp->num == 0)
402 {
403 fputc ('\n', out);
404 if (state->number == final_state->number)
405 fprintf (out, _(" $default\taccept\n"));
406 else
407 fprintf (out, _(" NO ACTIONS\n"));
408 return;
409 }
410
411 /* Print shifts. */
412 print_transitions (state, out, TRUE);
413 print_errs (out, state);
414 print_reductions (out, state);
415 /* Print gotos. */
416 print_transitions (state, out, FALSE);
417 }
418
419
420 /*--------------------------------------.
421 | Report all the data on STATE on OUT. |
422 `--------------------------------------*/
423
424 static void
425 print_state (FILE *out, state_t *state)
426 {
427 fputs ("\n\n", out);
428 fprintf (out, _("state %d"), state->number);
429 fputc ('\n', out);
430 print_core (out, state);
431 print_actions (out, state);
432 if ((report_flag & report_solved_conflicts)
433 && state->solved_conflicts)
434 fputs (state->solved_conflicts, out);
435 }
436 \f
437 /*-----------------------------------------.
438 | Print information on the whole grammar. |
439 `-----------------------------------------*/
440
441 #define END_TEST(End) \
442 do { \
443 if (column + strlen(buffer) > (End)) \
444 { \
445 fprintf (out, "%s\n ", buffer); \
446 column = 3; \
447 buffer[0] = 0; \
448 } \
449 } while (0)
450
451
452 static void
453 print_grammar (FILE *out)
454 {
455 symbol_number_t i;
456 char buffer[90];
457 int column = 0;
458
459 grammar_rules_print (out);
460
461 /* TERMINAL (type #) : rule #s terminal is on RHS */
462 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
463 for (i = 0; i < max_user_token_number + 1; i++)
464 if (token_translations[i] != undeftoken->number)
465 {
466 const char *tag = symbols[token_translations[i]]->tag;
467 rule_number_t r;
468 item_number_t *rhsp;
469
470 buffer[0] = 0;
471 column = strlen (tag);
472 fputs (tag, out);
473 END_TEST (50);
474 sprintf (buffer, " (%d)", i);
475
476 for (r = 1; r < nrules + 1; r++)
477 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
478 if (item_number_as_symbol_number (*rhsp) == token_translations[i])
479 {
480 END_TEST (65);
481 sprintf (buffer + strlen (buffer), " %d", r - 1);
482 break;
483 }
484 fprintf (out, "%s\n", buffer);
485 }
486 fputs ("\n\n", out);
487
488
489 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
490 for (i = ntokens; i < nsyms; i++)
491 {
492 int left_count = 0, right_count = 0;
493 rule_number_t r;
494 const char *tag = symbols[i]->tag;
495
496 for (r = 1; r < nrules + 1; r++)
497 {
498 item_number_t *rhsp;
499 if (rules[r].lhs->number == i)
500 left_count++;
501 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
502 if (item_number_as_symbol_number (*rhsp) == i)
503 {
504 right_count++;
505 break;
506 }
507 }
508
509 buffer[0] = 0;
510 fputs (tag, out);
511 column = strlen (tag);
512 sprintf (buffer, " (%d)", i);
513 END_TEST (0);
514
515 if (left_count > 0)
516 {
517 END_TEST (50);
518 sprintf (buffer + strlen (buffer), _(" on left:"));
519
520 for (r = 1; r < nrules + 1; r++)
521 {
522 END_TEST (65);
523 if (rules[r].lhs->number == i)
524 sprintf (buffer + strlen (buffer), " %d", r - 1);
525 }
526 }
527
528 if (right_count > 0)
529 {
530 if (left_count > 0)
531 sprintf (buffer + strlen (buffer), ",");
532 END_TEST (50);
533 sprintf (buffer + strlen (buffer), _(" on right:"));
534 for (r = 1; r < nrules + 1; r++)
535 {
536 item_number_t *rhsp;
537 for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
538 if (item_number_as_symbol_number (*rhsp) == i)
539 {
540 END_TEST (65);
541 sprintf (buffer + strlen (buffer), " %d", r - 1);
542 break;
543 }
544 }
545 }
546 fprintf (out, "%s\n", buffer);
547 }
548 }
549 \f
550 void
551 print_results (void)
552 {
553 state_number_t i;
554
555 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
556 that conflicts with Posix. */
557 FILE *out = xfopen (spec_verbose_file, "w");
558
559 reduce_output (out);
560 conflicts_output (out);
561
562 print_grammar (out);
563
564 /* If the whole state item sets, not only the kernels, are wanted,
565 `closure' will be run, which needs memory allocation/deallocation. */
566 if (report_flag & report_itemsets)
567 new_closure (nritems);
568 /* Storage for print_reductions. */
569 shiftset = bitset_create (ntokens, BITSET_FIXED);
570 lookaheadset = bitset_create (ntokens, BITSET_FIXED);
571 for (i = 0; i < nstates; i++)
572 print_state (out, states[i]);
573 bitset_free (shiftset);
574 bitset_free (lookaheadset);
575 if (report_flag & report_itemsets)
576 free_closure ();
577
578 xfclose (out);
579 }