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