]> git.saurik.com Git - bison.git/blame - src/print.c
Fix the `GAWK Grammar' failure.
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
09b503c8 2 Copyright 1984, 1986, 1989, 2000, 2001 Free Software Foundation, Inc.
e06f0c34 3
c29240e7 4 This file is part of Bison, the GNU Compiler Compiler.
e06f0c34 5
c29240e7
AD
6 Bison is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
e06f0c34 10
c29240e7
AD
11 Bison is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
e06f0c34 15
c29240e7
AD
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
e06f0c34
RS
20
21
e06f0c34 22#include "system.h"
8adfa272 23#include "quotearg.h"
e06f0c34
RS
24#include "files.h"
25#include "gram.h"
b2ca4022 26#include "LR0.h"
720d742f 27#include "lalr.h"
0619caf0 28#include "conflicts.h"
07a58c13
AD
29#include "getargs.h"
30#include "state.h"
b2ca4022 31#include "reader.h"
d7913476 32#include "print.h"
09b503c8 33#include "reduce.h"
43168960 34#include "closure.h"
e06f0c34 35
5092aba5
AD
36static unsigned *shiftset = NULL;
37static unsigned *lookaheadset = NULL;
38
07a58c13 39#if 0
4a120d45 40static void
d2729d44 41print_token (int extnum, int token)
e06f0c34 42{
342b8b6e 43 fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 44}
4a120d45 45#endif
e06f0c34 46
8adfa272
AD
47static inline const char *
48escape (const char *s)
49{
50 return quotearg_n_style (1, escape_quoting_style, s);
51}
52
53/* Be cautious not to use twice the same slot in a single expression. */
54static inline const char *
55escape2 (const char *s)
56{
57 return quotearg_n_style (2, escape_quoting_style, s);
58}
59
07a58c13 60\f
342b8b6e 61/*--------------------------------.
07a58c13 62| Report information on a state. |
342b8b6e 63`--------------------------------*/
e06f0c34 64
4a120d45 65static void
065fbd27 66print_core (FILE *out, state_t *state)
e06f0c34 67{
c29240e7 68 int i;
065fbd27
AD
69 short *sitems = state->items;
70 int snitems = state->nitems;
e06f0c34 71
43168960
AD
72 /* New experimental feature: if TRACE_FLAGS output all the items of
73 a state, not only its kernel. */
74 if (trace_flag)
75 {
76 closure (sitems, snitems);
77 sitems = itemset;
78 snitems = nitemset;
79 }
e06f0c34 80
43168960 81 if (snitems)
e06f0c34 82 {
43168960
AD
83 for (i = 0; i < snitems; i++)
84 {
85 short *sp;
86 short *sp1;
87 int rule;
4bc30f78 88
43168960 89 sp1 = sp = ritem + sitems[i];
e06f0c34 90
75142d45 91 while (*sp >= 0)
43168960 92 sp++;
e06f0c34 93
43168960 94 rule = -(*sp);
8adfa272 95 fprintf (out, " %s -> ", escape (tags[rule_table[rule].lhs]));
e06f0c34 96
43168960 97 for (sp = ritem + rule_table[rule].rhs; sp < sp1; sp++)
8adfa272 98 fprintf (out, "%s ", escape (tags[*sp]));
e06f0c34 99
43168960 100 fputc ('.', out);
e06f0c34 101
75142d45 102 for (/* Nothing */; *sp >= 0; ++sp)
8adfa272 103 fprintf (out, " %s", escape (tags[*sp]));
43168960 104
30171f79 105 fprintf (out, _(" (rule %d)"), rule - 1);
43168960
AD
106 fputc ('\n', out);
107 }
e06f0c34 108
342b8b6e 109 fputc ('\n', out);
e06f0c34 110 }
e06f0c34
RS
111}
112
5092aba5 113
4a120d45 114static void
5092aba5 115print_shifts (FILE *out, state_t *state)
e06f0c34 116{
c29240e7 117 int i;
5092aba5 118 shifts *shiftp = state->shifts;
e06f0c34 119
2e729273 120 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
d954473d
AD
121 if (!SHIFT_IS_DISABLED (shiftp, i))
122 {
123 int state1 = shiftp->shifts[i];
f693ad14 124 int symbol = state_table[state1]->accessing_symbol;
2e729273
AD
125 fprintf (out,
126 _(" %-4s\tshift, and go to state %d\n"),
8adfa272 127 escape (tags[symbol]), state1);
d954473d 128 }
e06f0c34 129
d954473d
AD
130 if (i > 0)
131 fputc ('\n', out);
5092aba5 132}
e06f0c34 133
e06f0c34 134
5092aba5
AD
135static void
136print_errs (FILE *out, state_t *state)
137{
138 errs *errp = state->errs;
139 int i;
140
5092aba5
AD
141 for (i = 0; i < errp->nerrs; ++i)
142 if (errp->errs[i])
143 fprintf (out, _(" %-4s\terror (nonassociative)\n"),
8adfa272 144 escape (tags[errp->errs[i]]));
5092aba5
AD
145
146 if (i > 0)
2cec70b9 147 fputc ('\n', out);
5092aba5 148}
e06f0c34 149
5092aba5
AD
150
151static void
152print_gotos (FILE *out, state_t *state)
153{
154 int i;
155 shifts *shiftp = state->shifts;
156
157 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
158 /* Skip token shifts. */;
e06f0c34 159
d954473d 160 if (i < shiftp->nshifts)
e06f0c34 161 {
d954473d
AD
162 for (; i < shiftp->nshifts; i++)
163 if (!SHIFT_IS_DISABLED (shiftp, i))
164 {
165 int state1 = shiftp->shifts[i];
f693ad14 166 int symbol = state_table[state1]->accessing_symbol;
d954473d 167 fprintf (out, _(" %-4s\tgo to state %d\n"),
8adfa272 168 escape (tags[symbol]), state1);
d954473d 169 }
e06f0c34 170
342b8b6e 171 fputc ('\n', out);
e06f0c34
RS
172 }
173}
174
5092aba5
AD
175static void
176print_reductions (FILE *out, state_t *state)
177{
178 int i;
179 shifts *shiftp = state->shifts;
180 reductions *redp = state->reductions;
181 errs *errp = state->errs;
182 int nodefault = 0;
183
80dac38c
AD
184 if (redp->nreds == 0)
185 return;
186
5092aba5
AD
187 if (state->consistent)
188 {
189 int rule = redp->rules[0];
190 int symbol = rule_table[rule].lhs;
191 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
30171f79 192 rule - 1, escape (tags[symbol]));
5092aba5
AD
193 return;
194 }
195
196 for (i = 0; i < tokensetsize; i++)
197 shiftset[i] = 0;
198
199 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
200 if (!SHIFT_IS_DISABLED (shiftp, i))
201 {
202 /* if this state has a shift for the error token, don't use a
203 default rule. */
204 if (SHIFT_IS_ERROR (shiftp, i))
205 nodefault = 1;
206 SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
207 }
208
2cec70b9
AD
209 for (i = 0; i < errp->nerrs; i++)
210 if (errp->errs[i])
211 SETBIT (shiftset, errp->errs[i]);
5092aba5
AD
212
213 if (state->nlookaheads == 1 && !nodefault)
214 {
215 int k;
216 int default_rule = LAruleno[state->lookaheadsp];
217
218 for (k = 0; k < tokensetsize; ++k)
219 lookaheadset[k] = LA (state->lookaheadsp)[k] & shiftset[k];
220
221 for (i = 0; i < ntokens; i++)
222 if (BITISSET (lookaheadset, i))
223 fprintf (out, _(" %-4s\t[reduce using rule %d (%s)]\n"),
30171f79 224 escape (tags[i]), default_rule - 1,
8adfa272 225 escape2 (tags[rule_table[default_rule].lhs]));
5092aba5
AD
226
227 fprintf (out, _(" $default\treduce using rule %d (%s)\n\n"),
30171f79 228 default_rule - 1, escape (tags[rule_table[default_rule].lhs]));
5092aba5
AD
229 }
230 else if (state->nlookaheads >= 1)
231 {
232 int cmax = 0;
233 int default_LA = -1;
234 int default_rule = 0;
235
236 if (!nodefault)
237 for (i = 0; i < state->nlookaheads; ++i)
238 {
239 int count = 0;
240 int j, k;
241
242 for (k = 0; k < tokensetsize; ++k)
243 lookaheadset[k] = LA (state->lookaheadsp + i)[k] & ~shiftset[k];
244
245 for (j = 0; j < ntokens; j++)
246 if (BITISSET (lookaheadset, j))
247 count++;
248
249 if (count > cmax)
250 {
251 cmax = count;
252 default_LA = state->lookaheadsp + i;
253 default_rule = LAruleno[state->lookaheadsp + i];
254 }
255
256 for (k = 0; k < tokensetsize; ++k)
257 shiftset[k] |= lookaheadset[k];
258 }
259
260 for (i = 0; i < tokensetsize; i++)
261 shiftset[i] = 0;
262
263 for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
264 if (!SHIFT_IS_DISABLED (shiftp, i))
265 SETBIT (shiftset, SHIFT_SYMBOL (shiftp, i));
266
267 for (i = 0; i < ntokens; i++)
268 {
269 int j;
270 int defaulted = 0;
271 int count = BITISSET (shiftset, i);
272
273 for (j = 0; j < state->nlookaheads; ++j)
274 {
275 if (BITISSET (LA (state->lookaheadsp + j), i))
276 {
277 if (count == 0)
278 {
279 if (state->lookaheadsp + j != default_LA)
280 fprintf (out,
281 _(" %-4s\treduce using rule %d (%s)\n"),
8adfa272 282 escape (tags[i]),
30171f79 283 LAruleno[state->lookaheadsp + j] - 1,
8adfa272 284 escape2 (tags[rule_table[LAruleno[state->lookaheadsp + j]].lhs]));
5092aba5
AD
285 else
286 defaulted = 1;
287
288 count++;
289 }
290 else
291 {
292 if (defaulted)
293 fprintf (out,
294 _(" %-4s\treduce using rule %d (%s)\n"),
8adfa272 295 escape (tags[i]),
30171f79 296 LAruleno[default_LA] - 1,
8adfa272 297 escape2 (tags[rule_table[LAruleno[default_LA]].lhs]));
5092aba5
AD
298 defaulted = 0;
299 fprintf (out,
300 _(" %-4s\t[reduce using rule %d (%s)]\n"),
8adfa272 301 escape (tags[i]),
30171f79 302 LAruleno[state->lookaheadsp + j] - 1,
8adfa272 303 escape2 (tags[rule_table[LAruleno[state->lookaheadsp + j]].lhs]));
5092aba5
AD
304 }
305 }
306 }
307 }
308
309 if (default_LA >= 0)
310 fprintf (out, _(" $default\treduce using rule %d (%s)\n"),
30171f79
AD
311 default_rule - 1,
312 escape (tags[rule_table[default_rule].lhs]));
5092aba5
AD
313 }
314}
315
316
317static void
318print_actions (FILE *out, state_t *state)
319{
320 reductions *redp = state->reductions;
321 shifts *shiftp = state->shifts;
322
80dac38c 323 if (shiftp->nshifts == 0 && redp->nreds == 0)
5092aba5
AD
324 {
325 if (final_state == state->number)
30171f79 326 fprintf (out, _(" $default\taccept\n"));
5092aba5 327 else
30171f79 328 fprintf (out, _(" NO ACTIONS\n"));
5092aba5
AD
329 return;
330 }
331
332 print_shifts (out, state);
333 print_errs (out, state);
80dac38c 334 print_reductions (out, state);
5092aba5
AD
335 print_gotos (out, state);
336}
337
07a58c13 338static void
065fbd27 339print_state (FILE *out, state_t *state)
07a58c13 340{
065fbd27 341 fprintf (out, _("state %d"), state->number);
342b8b6e
AD
342 fputs ("\n\n", out);
343 print_core (out, state);
344 print_actions (out, state);
d2d1b42b 345 fputs ("\n\n", out);
07a58c13
AD
346}
347\f
348/*-----------------------------------------.
349| Print information on the whole grammar. |
350`-----------------------------------------*/
351
342b8b6e
AD
352#define END_TEST(End) \
353do { \
354 if (column + strlen(buffer) > (End)) \
355 { \
356 fprintf (out, "%s\n ", buffer); \
357 column = 3; \
358 buffer[0] = 0; \
359 } \
ff4423cc 360} while (0)
e06f0c34 361
07a58c13 362
4a120d45 363static void
342b8b6e 364print_grammar (FILE *out)
e06f0c34
RS
365{
366 int i, j;
c29240e7 367 short *rule;
e06f0c34
RS
368 char buffer[90];
369 int column = 0;
370
371 /* rule # : LHS -> RHS */
d2d1b42b 372 fprintf (out, "%s\n\n", _("Grammar"));
b29b2ed5 373 fprintf (out, " %s\n", _("Number, Line, Rule"));
e06f0c34
RS
374 for (i = 1; i <= nrules; i++)
375 /* Don't print rules disabled in reduce_grammar_tables. */
68f1e3ed 376 if (rule_table[i].useful)
e06f0c34 377 {
b29b2ed5 378 fprintf (out, _(" %3d %3d %s ->"),
30171f79 379 i - 1, rule_table[i].line, escape (tags[rule_table[i].lhs]));
b2ed6e58 380 rule = &ritem[rule_table[i].rhs];
75142d45
AD
381 if (*rule >= 0)
382 while (*rule >= 0)
8adfa272 383 fprintf (out, " %s", escape (tags[*rule++]));
e06f0c34 384 else
b29b2ed5 385 fprintf (out, " /* %s */", _("empty"));
0df87bb6 386 fputc ('\n', out);
e06f0c34 387 }
d2d1b42b
AD
388 fputs ("\n\n", out);
389
e06f0c34
RS
390
391 /* TERMINAL (type #) : rule #s terminal is on RHS */
d2d1b42b 392 fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
342b8b6e
AD
393 for (i = 0; i <= max_user_token_number; i++)
394 if (token_translations[i] != 2)
395 {
396 buffer[0] = 0;
8adfa272
AD
397 column = strlen (escape (tags[token_translations[i]]));
398 fputs (escape (tags[token_translations[i]]), out);
342b8b6e
AD
399 END_TEST (50);
400 sprintf (buffer, " (%d)", i);
e06f0c34 401
342b8b6e 402 for (j = 1; j <= nrules; j++)
75142d45 403 for (rule = &ritem[rule_table[j].rhs]; *rule >= 0; rule++)
342b8b6e
AD
404 if (*rule == token_translations[i])
405 {
406 END_TEST (65);
30171f79 407 sprintf (buffer + strlen (buffer), " %d", j - 1);
342b8b6e
AD
408 break;
409 }
410 fprintf (out, "%s\n", buffer);
411 }
d2d1b42b
AD
412 fputs ("\n\n", out);
413
342b8b6e 414
d2d1b42b 415 fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
e06f0c34
RS
416 for (i = ntokens; i <= nsyms - 1; i++)
417 {
418 int left_count = 0, right_count = 0;
419
420 for (j = 1; j <= nrules; j++)
421 {
b2ed6e58 422 if (rule_table[j].lhs == i)
e06f0c34 423 left_count++;
75142d45 424 for (rule = &ritem[rule_table[j].rhs]; *rule >= 0; rule++)
e06f0c34
RS
425 if (*rule == i)
426 {
427 right_count++;
428 break;
429 }
430 }
431
432 buffer[0] = 0;
8adfa272
AD
433 fputs (escape (tags[i]), out);
434 column = strlen (escape (tags[i]));
e06f0c34
RS
435 sprintf (buffer, " (%d)", i);
436 END_TEST (0);
437
438 if (left_count > 0)
439 {
440 END_TEST (50);
c29240e7 441 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34
RS
442
443 for (j = 1; j <= nrules; j++)
444 {
445 END_TEST (65);
b2ed6e58 446 if (rule_table[j].lhs == i)
30171f79 447 sprintf (buffer + strlen (buffer), " %d", j - 1);
e06f0c34
RS
448 }
449 }
450
451 if (right_count > 0)
452 {
453 if (left_count > 0)
c29240e7 454 sprintf (buffer + strlen (buffer), ",");
e06f0c34 455 END_TEST (50);
c29240e7 456 sprintf (buffer + strlen (buffer), _(" on right:"));
e06f0c34
RS
457 for (j = 1; j <= nrules; j++)
458 {
75142d45 459 for (rule = &ritem[rule_table[j].rhs]; *rule >= 0; rule++)
e06f0c34
RS
460 if (*rule == i)
461 {
462 END_TEST (65);
30171f79 463 sprintf (buffer + strlen (buffer), " %d", j - 1);
e06f0c34
RS
464 break;
465 }
466 }
467 }
342b8b6e 468 fprintf (out, "%s\n", buffer);
e06f0c34 469 }
d2d1b42b 470 fputs ("\n\n", out);
e06f0c34 471}
07a58c13
AD
472\f
473void
474print_results (void)
475{
64d15509 476 int i;
07a58c13 477
64d15509
AD
478 /* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
479 that conflicts with Posix. */
480 FILE *out = xfopen (spec_verbose_file, "w");
07a58c13 481
64d15509
AD
482 size_t size = obstack_object_size (&output_obstack);
483 fwrite (obstack_finish (&output_obstack), 1, size, out);
484 obstack_free (&output_obstack, NULL);
07a58c13 485
64d15509
AD
486 if (size)
487 fputs ("\n\n", out);
342b8b6e 488
64d15509
AD
489 reduce_output (out);
490 conflicts_output (out);
342b8b6e 491
64d15509 492 print_grammar (out);
342b8b6e 493
5092aba5
AD
494 /* New experimental feature: output all the items of a state, not
495 only its kernel. Requires to run closure, which need memory
496 allocation/deallocation. */
64d15509 497 if (trace_flag)
9e7f6bbd 498 new_closure (nritems);
5092aba5
AD
499 /* Storage for print_reductions. */
500 shiftset = XCALLOC (unsigned, tokensetsize);
501 lookaheadset = XCALLOC (unsigned, tokensetsize);
64d15509 502 for (i = 0; i < nstates; i++)
065fbd27 503 print_state (out, state_table[i]);
5092aba5
AD
504 free (shiftset);
505 free (lookaheadset);
64d15509
AD
506 if (trace_flag)
507 free_closure ();
508
509 xfclose (out);
07a58c13 510}