]> git.saurik.com Git - bison.git/blame - src/print.c
* src/nullable.h: New file.
[bison.git] / src / print.c
CommitLineData
e06f0c34 1/* Print information on generated parser, for bison,
c29240e7 2 Copyright (C) 1984, 1986, 1989, 2000 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"
7612000c 23#include "alloc.h"
e06f0c34
RS
24#include "files.h"
25#include "gram.h"
26#include "state.h"
720d742f 27#include "lalr.h"
e06f0c34
RS
28
29extern char **tags;
30extern int nstates;
e06f0c34 31extern errs **err_table;
e06f0c34
RS
32extern char any_conflicts;
33extern char *conflicts;
34extern int final_state;
35
c29240e7
AD
36extern void conflict_log PARAMS ((void));
37extern void verbose_conflict_log PARAMS ((void));
38extern void print_reductions PARAMS ((int));
d2729d44 39
c29240e7
AD
40extern void terse PARAMS ((void));
41extern void verbose PARAMS ((void));
4a120d45 42
c29240e7
AD
43#if 0 /* XXX currently unused. */
44static void print_token PARAMS ((int, int));
4a120d45
JT
45#endif
46
c29240e7
AD
47static void print_state PARAMS ((int));
48static void print_core PARAMS ((int));
49static void print_actions PARAMS ((int));
50static void print_grammar PARAMS ((void));
e06f0c34
RS
51
52void
d2729d44 53terse (void)
e06f0c34
RS
54{
55 if (any_conflicts)
c29240e7 56 conflict_log ();
e06f0c34
RS
57}
58
59
60void
d2729d44 61verbose (void)
e06f0c34 62{
c29240e7 63 int i;
e06f0c34
RS
64
65 if (any_conflicts)
c29240e7 66 verbose_conflict_log ();
e06f0c34 67
c29240e7 68 print_grammar ();
e06f0c34
RS
69
70 for (i = 0; i < nstates; i++)
c29240e7 71 print_state (i);
e06f0c34
RS
72}
73
74
c29240e7 75#if 0 /* XXX currently unused. */
4a120d45 76static void
d2729d44 77print_token (int extnum, int token)
e06f0c34 78{
c29240e7 79 fprintf (foutput, _(" type %d is %s\n"), extnum, tags[token]);
e06f0c34 80}
4a120d45 81#endif
e06f0c34
RS
82
83
4a120d45 84static void
d2729d44 85print_state (int state)
e06f0c34 86{
c29240e7
AD
87 fprintf (foutput, _("\n\nstate %d\n\n"), state);
88 print_core (state);
89 print_actions (state);
e06f0c34
RS
90}
91
92
4a120d45 93static void
d2729d44 94print_core (int state)
e06f0c34 95{
c29240e7
AD
96 int i;
97 int k;
98 int rule;
99 core *statep;
100 short *sp;
101 short *sp1;
e06f0c34
RS
102
103 statep = state_table[state];
104 k = statep->nitems;
105
c29240e7
AD
106 if (k == 0)
107 return;
e06f0c34
RS
108
109 for (i = 0; i < k; i++)
110 {
111 sp1 = sp = ritem + statep->items[i];
112
113 while (*sp > 0)
114 sp++;
115
116 rule = -(*sp);
c29240e7 117 fprintf (foutput, " %s -> ", tags[rlhs[rule]]);
e06f0c34
RS
118
119 for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
120 {
c29240e7 121 fprintf (foutput, "%s ", tags[*sp]);
e06f0c34
RS
122 }
123
c29240e7 124 putc ('.', foutput);
e06f0c34
RS
125
126 while (*sp > 0)
127 {
c29240e7 128 fprintf (foutput, " %s", tags[*sp]);
e06f0c34
RS
129 sp++;
130 }
131
a083fbbf 132 fprintf (foutput, _(" (rule %d)"), rule);
c29240e7 133 putc ('\n', foutput);
e06f0c34
RS
134 }
135
c29240e7 136 putc ('\n', foutput);
e06f0c34
RS
137}
138
139
4a120d45 140static void
d2729d44 141print_actions (int state)
e06f0c34 142{
c29240e7
AD
143 int i;
144 int k;
145 int state1;
146 int symbol;
147 shifts *shiftp;
148 errs *errp;
149 reductions *redp;
150 int rule;
e06f0c34
RS
151
152 shiftp = shift_table[state];
153 redp = reduction_table[state];
154 errp = err_table[state];
155
156 if (!shiftp && !redp)
157 {
158 if (final_state == state)
c29240e7 159 fprintf (foutput, _(" $default\taccept\n"));
e06f0c34 160 else
c29240e7 161 fprintf (foutput, _(" NO ACTIONS\n"));
e06f0c34
RS
162 return;
163 }
164
165 if (shiftp)
166 {
167 k = shiftp->nshifts;
168
169 for (i = 0; i < k; i++)
170 {
c29240e7
AD
171 if (!shiftp->shifts[i])
172 continue;
e06f0c34
RS
173 state1 = shiftp->shifts[i];
174 symbol = accessing_symbol[state1];
175 /* The following line used to be turned off. */
c29240e7
AD
176 if (ISVAR (symbol))
177 break;
178 if (symbol == 0) /* I.e. strcmp(tags[symbol],"$")==0 */
179 fprintf (foutput, _(" $ \tgo to state %d\n"), state1);
180 else
181 fprintf (foutput, _(" %-4s\tshift, and go to state %d\n"),
182 tags[symbol], state1);
e06f0c34
RS
183 }
184
185 if (i > 0)
c29240e7 186 putc ('\n', foutput);
e06f0c34
RS
187 }
188 else
189 {
190 i = 0;
191 k = 0;
192 }
193
194 if (errp)
195 {
196 int j, nerrs;
197
198 nerrs = errp->nerrs;
199
200 for (j = 0; j < nerrs; j++)
201 {
c29240e7
AD
202 if (!errp->errs[j])
203 continue;
e06f0c34 204 symbol = errp->errs[j];
c29240e7
AD
205 fprintf (foutput, _(" %-4s\terror (nonassociative)\n"),
206 tags[symbol]);
e06f0c34
RS
207 }
208
209 if (j > 0)
c29240e7 210 putc ('\n', foutput);
e06f0c34
RS
211 }
212
213 if (consistent[state] && redp)
214 {
215 rule = redp->rules[0];
216 symbol = rlhs[rule];
c29240e7
AD
217 fprintf (foutput, _(" $default\treduce using rule %d (%s)\n\n"),
218 rule, tags[symbol]);
e06f0c34
RS
219 }
220 else if (redp)
221 {
c29240e7 222 print_reductions (state);
e06f0c34
RS
223 }
224
225 if (i < k)
226 {
227 for (; i < k; i++)
228 {
c29240e7
AD
229 if (!shiftp->shifts[i])
230 continue;
e06f0c34
RS
231 state1 = shiftp->shifts[i];
232 symbol = accessing_symbol[state1];
c29240e7
AD
233 fprintf (foutput, _(" %-4s\tgo to state %d\n"), tags[symbol],
234 state1);
e06f0c34
RS
235 }
236
c29240e7 237 putc ('\n', foutput);
e06f0c34
RS
238 }
239}
240
4a120d45
JT
241#define END_TEST(end) \
242 do { \
243 if (column + strlen(buffer) > (end)) { \
244 fprintf (foutput, "%s\n ", buffer); \
245 column = 3; \
246 buffer[0] = 0; \
247 } \
248 } while (0)
e06f0c34 249
4a120d45 250static void
d2729d44 251print_grammar (void)
e06f0c34
RS
252{
253 int i, j;
c29240e7 254 short *rule;
e06f0c34
RS
255 char buffer[90];
256 int column = 0;
257
258 /* rule # : LHS -> RHS */
c29240e7 259 fputs (_("\nGrammar\n"), foutput);
e06f0c34
RS
260 for (i = 1; i <= nrules; i++)
261 /* Don't print rules disabled in reduce_grammar_tables. */
262 if (rlhs[i] >= 0)
263 {
c29240e7 264 fprintf (foutput, _("rule %-4d %s ->"), i, tags[rlhs[i]]);
e06f0c34
RS
265 rule = &ritem[rrhs[i]];
266 if (*rule > 0)
267 while (*rule > 0)
c29240e7 268 fprintf (foutput, " %s", tags[*rule++]);
e06f0c34 269 else
a083fbbf 270 fputs (_(" /* empty */"), foutput);
c29240e7 271 putc ('\n', foutput);
e06f0c34
RS
272 }
273
274 /* TERMINAL (type #) : rule #s terminal is on RHS */
c29240e7
AD
275 fputs (_("\nTerminals, with rules where they appear\n\n"), foutput);
276 fprintf (foutput, "%s (-1)\n", tags[0]);
e06f0c34
RS
277 if (translations)
278 {
279 for (i = 0; i <= max_user_token_number; i++)
280 if (token_translations[i] != 2)
281 {
282 buffer[0] = 0;
283 column = strlen (tags[token_translations[i]]);
c29240e7 284 fprintf (foutput, "%s", tags[token_translations[i]]);
e06f0c34
RS
285 END_TEST (50);
286 sprintf (buffer, " (%d)", i);
287
288 for (j = 1; j <= nrules; j++)
289 {
290 for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
291 if (*rule == token_translations[i])
292 {
293 END_TEST (65);
c29240e7 294 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
295 break;
296 }
297 }
298 fprintf (foutput, "%s\n", buffer);
299 }
300 }
301 else
302 for (i = 1; i < ntokens; i++)
303 {
304 buffer[0] = 0;
305 column = strlen (tags[i]);
c29240e7 306 fprintf (foutput, "%s", tags[i]);
e06f0c34
RS
307 END_TEST (50);
308 sprintf (buffer, " (%d)", i);
309
310 for (j = 1; j <= nrules; j++)
311 {
312 for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
313 if (*rule == i)
314 {
315 END_TEST (65);
c29240e7 316 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
317 break;
318 }
319 }
320 fprintf (foutput, "%s\n", buffer);
321 }
322
c29240e7 323 fputs (_("\nNonterminals, with rules where they appear\n\n"), foutput);
e06f0c34
RS
324 for (i = ntokens; i <= nsyms - 1; i++)
325 {
326 int left_count = 0, right_count = 0;
327
328 for (j = 1; j <= nrules; j++)
329 {
330 if (rlhs[j] == i)
331 left_count++;
332 for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
333 if (*rule == i)
334 {
335 right_count++;
336 break;
337 }
338 }
339
340 buffer[0] = 0;
c29240e7 341 fprintf (foutput, "%s", tags[i]);
e06f0c34
RS
342 column = strlen (tags[i]);
343 sprintf (buffer, " (%d)", i);
344 END_TEST (0);
345
346 if (left_count > 0)
347 {
348 END_TEST (50);
c29240e7 349 sprintf (buffer + strlen (buffer), _(" on left:"));
e06f0c34
RS
350
351 for (j = 1; j <= nrules; j++)
352 {
353 END_TEST (65);
354 if (rlhs[j] == i)
c29240e7 355 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
356 }
357 }
358
359 if (right_count > 0)
360 {
361 if (left_count > 0)
c29240e7 362 sprintf (buffer + strlen (buffer), ",");
e06f0c34 363 END_TEST (50);
c29240e7 364 sprintf (buffer + strlen (buffer), _(" on right:"));
e06f0c34
RS
365 for (j = 1; j <= nrules; j++)
366 {
367 for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
368 if (*rule == i)
369 {
370 END_TEST (65);
c29240e7 371 sprintf (buffer + strlen (buffer), " %d", j);
e06f0c34
RS
372 break;
373 }
374 }
375 }
376 fprintf (foutput, "%s\n", buffer);
377 }
378}