]> git.saurik.com Git - bison.git/blob - src/gram.c
(muscle_entry_t): Remove; moved to muscle_tab.c and renamed to muscle_entry.
[bison.git] / src / gram.c
1 /* Allocate input grammar variables for bison,
2 Copyright (C) 1984, 1986, 1989, 2001, 2002 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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 #include "system.h"
23
24 #include <quotearg.h>
25
26 #include "gram.h"
27 #include "reader.h"
28 #include "reduce.h"
29 #include "symtab.h"
30
31 /* Comments for these variables are in gram.h. */
32
33 item_number *ritem = NULL;
34 unsigned int nritems = 0;
35
36 rule *rules = NULL;
37 rule_number nrules = 0;
38
39 symbol **symbols = NULL;
40 int nsyms = 0;
41 int ntokens = 1;
42 int nvars = 0;
43
44 symbol_number *token_translations = NULL;
45
46 int max_user_token_number = 256;
47
48 int glr_parser = 0;
49 int pure_parser = 0;
50
51
52 /*--------------------------------------------------------------.
53 | Return true IFF the rule has a `number' smaller than NRULES. |
54 `--------------------------------------------------------------*/
55
56 bool
57 rule_useful_p (rule *r)
58 {
59 return r->number < nrules;
60 }
61
62
63 /*-------------------------------------------------------------.
64 | Return true IFF the rule has a `number' higher than NRULES. |
65 `-------------------------------------------------------------*/
66
67 bool
68 rule_useless_p (rule *r)
69 {
70 return r->number >= nrules;
71 }
72
73
74 /*--------------------------------------------------------------------.
75 | Return true IFF the rule is not flagged as useful *and* is useful. |
76 | In other words, it was discarded because of conflicts. |
77 `--------------------------------------------------------------------*/
78
79 bool
80 rule_never_reduced_p (rule *r)
81 {
82 return !r->useful && r->number < nrules;
83 }
84
85
86 /*----------------------------------------------------------------.
87 | Print this RULE's number and lhs on OUT. If a PREVIOUS_LHS was |
88 | already displayed (by a previous call for another rule), avoid |
89 | useless repetitions. |
90 `----------------------------------------------------------------*/
91
92 void
93 rule_lhs_print (rule *r, symbol *previous_lhs, FILE *out)
94 {
95 fprintf (out, " %3d ", r->number);
96 if (previous_lhs != r->lhs)
97 {
98 fprintf (out, "%s:", r->lhs->tag);
99 }
100 else
101 {
102 int n;
103 for (n = strlen (previous_lhs->tag); n > 0; --n)
104 fputc (' ', out);
105 fputc ('|', out);
106 }
107 }
108
109
110 /*--------------------------------------.
111 | Return the number of symbols in RHS. |
112 `--------------------------------------*/
113
114 int
115 rule_rhs_length (rule *r)
116 {
117 int res = 0;
118 item_number *rhsp;
119 for (rhsp = r->rhs; *rhsp >= 0; ++rhsp)
120 ++res;
121 return res;
122 }
123
124
125 /*-------------------------------.
126 | Print this rule's RHS on OUT. |
127 `-------------------------------*/
128
129 void
130 rule_rhs_print (rule *r, FILE *out)
131 {
132 if (*r->rhs >= 0)
133 {
134 item_number *rp;
135 for (rp = r->rhs; *rp >= 0; rp++)
136 fprintf (out, " %s", symbols[*rp]->tag);
137 fputc ('\n', out);
138 }
139 else
140 {
141 fprintf (out, " /* %s */\n", _("empty"));
142 }
143 }
144
145
146 /*-------------------------.
147 | Print this rule on OUT. |
148 `-------------------------*/
149
150 void
151 rule_print (rule *r, FILE *out)
152 {
153 fprintf (out, "%s:", r->lhs->tag);
154 rule_rhs_print (r, out);
155 }
156
157
158 /*------------------------.
159 | Dump RITEM for traces. |
160 `------------------------*/
161
162 void
163 ritem_print (FILE *out)
164 {
165 unsigned int i;
166 fputs ("RITEM\n", out);
167 for (i = 0; i < nritems; ++i)
168 if (ritem[i] >= 0)
169 fprintf (out, " %s", symbols[ritem[i]]->tag);
170 else
171 fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i]));
172 fputs ("\n\n", out);
173 }
174
175
176 /*------------------------------------------.
177 | Return the size of the longest rule RHS. |
178 `------------------------------------------*/
179
180 size_t
181 ritem_longest_rhs (void)
182 {
183 int max = 0;
184 rule_number r;
185
186 for (r = 0; r < nrules; ++r)
187 {
188 int length = rule_rhs_length (&rules[r]);
189 if (length > max)
190 max = length;
191 }
192
193 return max;
194 }
195
196
197 /*-----------------------------------------------------------------.
198 | Print the grammar's rules that match FILTER on OUT under TITLE. |
199 `-----------------------------------------------------------------*/
200
201 void
202 grammar_rules_partial_print (FILE *out, const char *title,
203 rule_filter filter)
204 {
205 int r;
206 bool first = true;
207 symbol *previous_lhs = NULL;
208
209 /* rule # : LHS -> RHS */
210 for (r = 0; r < nrules + nuseless_productions; r++)
211 {
212 if (filter && !filter (&rules[r]))
213 continue;
214 if (first)
215 fprintf (out, "%s\n\n", title);
216 else if (previous_lhs && previous_lhs != rules[r].lhs)
217 fputc ('\n', out);
218 first = false;
219 rule_lhs_print (&rules[r], previous_lhs, out);
220 rule_rhs_print (&rules[r], out);
221 previous_lhs = rules[r].lhs;
222 }
223 if (!first)
224 fputs ("\n\n", out);
225 }
226
227
228 /*------------------------------------------.
229 | Print the grammar's useful rules on OUT. |
230 `------------------------------------------*/
231
232 void
233 grammar_rules_print (FILE *out)
234 {
235 grammar_rules_partial_print (out, _("Grammar"), rule_useful_p);
236 }
237
238
239 /*-------------------.
240 | Dump the grammar. |
241 `-------------------*/
242
243 void
244 grammar_dump (FILE *out, const char *title)
245 {
246 fprintf (out, "%s\n\n", title);
247 fprintf (out,
248 "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
249 ntokens, nvars, nsyms, nrules, nritems);
250
251
252 fprintf (out, "Variables\n---------\n\n");
253 {
254 symbol_number i;
255 fprintf (out, "Value Sprec Sassoc Tag\n");
256
257 for (i = ntokens; i < nsyms; i++)
258 fprintf (out, "%5d %5d %5d %s\n",
259 i,
260 symbols[i]->prec, symbols[i]->assoc,
261 symbols[i]->tag);
262 fprintf (out, "\n\n");
263 }
264
265 fprintf (out, "Rules\n-----\n\n");
266 {
267 rule_number i;
268 fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
269 for (i = 0; i < nrules + nuseless_productions; i++)
270 {
271 rule *rule_i = &rules[i];
272 item_number *r = NULL;
273 unsigned int rhs_itemno = rule_i->rhs - ritem;
274 unsigned int rhs_count = 0;
275 /* Find the last RHS index in ritems. */
276 for (r = rule_i->rhs; *r >= 0; ++r)
277 ++rhs_count;
278 fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
279 i,
280 rule_i->prec ? rule_i->prec->prec : 0,
281 rule_i->prec ? rule_i->prec->assoc : 0,
282 rule_i->useful,
283 rhs_itemno,
284 rhs_itemno + rhs_count - 1,
285 rule_i->lhs->number);
286 /* Dumped the RHS. */
287 for (r = rule_i->rhs; *r >= 0; r++)
288 fprintf (out, " %3d", *r);
289 fprintf (out, " [%d]\n", item_number_as_rule_number (*r));
290 }
291 }
292 fprintf (out, "\n\n");
293
294 fprintf (out, "Rules interpreted\n-----------------\n\n");
295 {
296 rule_number r;
297 for (r = 0; r < nrules + nuseless_productions; r++)
298 {
299 fprintf (out, "%-5d ", r);
300 rule_print (&rules[r], out);
301 }
302 }
303 fprintf (out, "\n\n");
304 }
305
306
307 /*------------------------------------------------------------------.
308 | Report on STDERR the rules that are not flagged USEFUL, using the |
309 | MESSAGE (which can be `useless rule' when invoked after grammar |
310 | reduction, or `never reduced' after conflicts were taken into |
311 | account). |
312 `------------------------------------------------------------------*/
313
314 void
315 grammar_rules_never_reduced_report (const char *message)
316 {
317 rule_number r;
318 for (r = 0; r < nrules ; ++r)
319 if (!rules[r].useful)
320 {
321 location_print (stderr, rules[r].location);
322 fprintf (stderr, ": %s: %s: ",
323 _("warning"), message);
324 rule_print (&rules[r], stderr);
325 }
326 }
327
328 void
329 grammar_free (void)
330 {
331 XFREE (ritem);
332 free (rules);
333 XFREE (token_translations);
334 /* Free the symbol table data structure. */
335 symbols_free ();
336 free_merger_functions ();
337 }