]> git.saurik.com Git - bison.git/blob - src/gram.c
tests: add -pedantic for --enable-gcc-warnings.
[bison.git] / src / gram.c
1 /* Allocate input grammar variables for Bison.
2
3 Copyright (C) 1984, 1986, 1989, 2001-2003, 2005-2011 Free Software
4 Foundation, Inc.
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include <config.h>
22 #include "system.h"
23
24 #include <quotearg.h>
25
26 #include "complain.h"
27 #include "getargs.h"
28 #include "gram.h"
29 #include "print-xml.h"
30 #include "reader.h"
31 #include "reduce.h"
32 #include "symtab.h"
33
34 /* Comments for these variables are in gram.h. */
35
36 item_number *ritem = NULL;
37 unsigned int nritems = 0;
38
39 rule *rules = NULL;
40 rule_number nrules = 0;
41
42 symbol **symbols = NULL;
43 int nsyms = 0;
44 int ntokens = 1;
45 int nvars = 0;
46
47 symbol_number *token_translations = NULL;
48
49 int max_user_token_number = 256;
50
51 bool
52 rule_useful_in_grammar_p (rule *r)
53 {
54 return r->number < nrules;
55 }
56
57 bool
58 rule_useless_in_grammar_p (rule *r)
59 {
60 return !rule_useful_in_grammar_p (r);
61 }
62
63 bool
64 rule_useless_in_parser_p (rule *r)
65 {
66 return !r->useful && rule_useful_in_grammar_p (r);
67 }
68
69 void
70 rule_lhs_print (rule *r, symbol *previous_lhs, FILE *out)
71 {
72 fprintf (out, " %3d ", r->number);
73 if (previous_lhs != r->lhs)
74 {
75 fprintf (out, "%s:", r->lhs->tag);
76 }
77 else
78 {
79 int n;
80 for (n = strlen (previous_lhs->tag); n > 0; --n)
81 fputc (' ', out);
82 fputc ('|', out);
83 }
84 }
85
86 void
87 rule_lhs_print_xml (rule *r, FILE *out, int level)
88 {
89 xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
90 }
91
92 int
93 rule_rhs_length (rule *r)
94 {
95 int res = 0;
96 item_number *rhsp;
97 for (rhsp = r->rhs; *rhsp >= 0; ++rhsp)
98 ++res;
99 return res;
100 }
101
102 void
103 rule_rhs_print (rule *r, FILE *out)
104 {
105 if (*r->rhs >= 0)
106 {
107 item_number *rp;
108 for (rp = r->rhs; *rp >= 0; rp++)
109 fprintf (out, " %s", symbols[*rp]->tag);
110 fputc ('\n', out);
111 }
112 else
113 {
114 fprintf (out, " /* %s */\n", _("empty"));
115 }
116 }
117
118 static void
119 rule_rhs_print_xml (rule *r, FILE *out, int level)
120 {
121 if (*r->rhs >= 0)
122 {
123 item_number *rp;
124 xml_puts (out, level, "<rhs>");
125 for (rp = r->rhs; *rp >= 0; rp++)
126 xml_printf (out, level + 1, "<symbol>%s</symbol>",
127 xml_escape (symbols[*rp]->tag));
128 xml_puts (out, level, "</rhs>");
129 }
130 else
131 {
132 xml_puts (out, level, "<rhs>");
133 xml_puts (out, level + 1, "<empty/>");
134 xml_puts (out, level, "</rhs>");
135 }
136 }
137
138 void
139 rule_print (rule *r, FILE *out)
140 {
141 fprintf (out, "%s:", r->lhs->tag);
142 rule_rhs_print (r, out);
143 }
144
145 void
146 ritem_print (FILE *out)
147 {
148 unsigned int i;
149 fputs ("RITEM\n", out);
150 for (i = 0; i < nritems; ++i)
151 if (ritem[i] >= 0)
152 fprintf (out, " %s", symbols[ritem[i]]->tag);
153 else
154 fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i]));
155 fputs ("\n\n", out);
156 }
157
158 size_t
159 ritem_longest_rhs (void)
160 {
161 int max = 0;
162 rule_number r;
163
164 for (r = 0; r < nrules; ++r)
165 {
166 int length = rule_rhs_length (&rules[r]);
167 if (length > max)
168 max = length;
169 }
170
171 return max;
172 }
173
174 void
175 grammar_rules_partial_print (FILE *out, const char *title,
176 rule_filter filter)
177 {
178 rule_number r;
179 bool first = true;
180 symbol *previous_lhs = NULL;
181
182 /* rule # : LHS -> RHS */
183 for (r = 0; r < nrules + nuseless_productions; r++)
184 {
185 if (filter && !filter (&rules[r]))
186 continue;
187 if (first)
188 fprintf (out, "%s\n\n", title);
189 else if (previous_lhs && previous_lhs != rules[r].lhs)
190 fputc ('\n', out);
191 first = false;
192 rule_lhs_print (&rules[r], previous_lhs, out);
193 rule_rhs_print (&rules[r], out);
194 previous_lhs = rules[r].lhs;
195 }
196 if (!first)
197 fputs ("\n\n", out);
198 }
199
200 void
201 grammar_rules_print (FILE *out)
202 {
203 grammar_rules_partial_print (out, _("Grammar"), rule_useful_in_grammar_p);
204 }
205
206 void
207 grammar_rules_print_xml (FILE *out, int level)
208 {
209 rule_number r;
210 bool first = true;
211
212 for (r = 0; r < nrules + nuseless_productions; r++)
213 {
214 if (first)
215 xml_puts (out, level + 1, "<rules>");
216 first = false;
217 {
218 char const *usefulness;
219 if (rule_useless_in_grammar_p (&rules[r]))
220 usefulness = "useless-in-grammar";
221 else if (rule_useless_in_parser_p (&rules[r]))
222 usefulness = "useless-in-parser";
223 else
224 usefulness = "useful";
225 xml_indent (out, level + 2);
226 fprintf (out, "<rule number=\"%d\" usefulness=\"%s\"",
227 rules[r].number, usefulness);
228 if (rules[r].precsym)
229 fprintf (out, " percent_prec=\"%s\"",
230 xml_escape (rules[r].precsym->tag));
231 fputs (">\n", out);
232 }
233 rule_lhs_print_xml (&rules[r], out, level + 3);
234 rule_rhs_print_xml (&rules[r], out, level + 3);
235 xml_puts (out, level + 2, "</rule>");
236 }
237 if (!first)
238 xml_puts (out, level + 1, "</rules>");
239 else
240 xml_puts (out, level + 1, "<rules/>");
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 *rp = 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 (rp = rule_i->rhs; *rp >= 0; ++rp)
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 (rp = rule_i->rhs; *rp >= 0; rp++)
288 fprintf (out, " %3d", *rp);
289 fprintf (out, " [%d]\n", item_number_as_rule_number (*rp));
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 void
307 grammar_rules_useless_report (const char *message)
308 {
309 rule_number r;
310 for (r = 0; r < nrules ; ++r)
311 if (!rules[r].useful)
312 {
313 warn_at (rules[r].location, "%s: ", message);
314 if (warnings_flag & warnings_other)
315 {
316 rule_print (&rules[r], stderr);
317 fflush (stderr);
318 }
319 }
320 }
321
322 void
323 grammar_free (void)
324 {
325 if (ritem)
326 free (ritem - 1);
327 free (rules);
328 free (token_translations);
329 /* Free the symbol table data structure. */
330 symbols_free ();
331 free_merger_functions ();
332 }