]> git.saurik.com Git - bison.git/blame - src/gram.c
tests: minor refactoring
[bison.git] / src / gram.c
CommitLineData
6f84e9ab
PE
1/* Allocate input grammar variables for Bison.
2
7d6bad19 3 Copyright (C) 1984, 1986, 1989, 2001-2003, 2005-2013 Free Software
575619af 4 Foundation, Inc.
f7d4d87a 5
076ab033 6 This file is part of Bison, the GNU Compiler Compiler.
f7d4d87a 7
f16b0819 8 This program is free software: you can redistribute it and/or modify
076ab033 9 it under the terms of the GNU General Public License as published by
f16b0819
PE
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
f7d4d87a 12
f16b0819 13 This program is distributed in the hope that it will be useful,
076ab033
AD
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.
f7d4d87a 17
076ab033 18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
f7d4d87a 20
2cec9080 21#include <config.h>
4a120d45 22#include "system.h"
81ebdef9 23
2bfcac9a 24#include "complain.h"
c39014ae 25#include "getargs.h"
78ab8f67 26#include "gram.h"
2bfcac9a 27#include "print-xml.h"
3067fbef 28#include "reader.h"
81ebdef9
PE
29#include "reduce.h"
30#include "symtab.h"
4a120d45 31
6b98e4b5 32/* Comments for these variables are in gram.h. */
f7d4d87a 33
81ebdef9 34item_number *ritem = NULL;
0c2d3f4c 35unsigned int nritems = 0;
75142d45 36
81ebdef9
PE
37rule *rules = NULL;
38rule_number nrules = 0;
0e78e603 39
81ebdef9 40symbol **symbols = NULL;
5123689b
AD
41int nsyms = 0;
42int ntokens = 1;
43int nvars = 0;
44
81ebdef9 45symbol_number *token_translations = NULL;
f7d4d87a 46
280a38c3 47int max_user_token_number = 256;
f7d4d87a 48
c8f002c7 49bool
510c8497 50rule_useful_in_grammar_p (rule const *r)
c8f002c7
AD
51{
52 return r->number < nrules;
53}
54
c8f002c7 55bool
510c8497 56rule_useless_in_grammar_p (rule const *r)
c8f002c7 57{
cff03fb2 58 return !rule_useful_in_grammar_p (r);
c8f002c7
AD
59}
60
c8f002c7 61bool
510c8497 62rule_useless_in_parser_p (rule const *r)
c8f002c7 63{
cff03fb2 64 return !r->useful && rule_useful_in_grammar_p (r);
c8f002c7
AD
65}
66
ce4ccb4b 67void
510c8497 68rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out)
ce4ccb4b 69{
81ebdef9
PE
70 fprintf (out, " %3d ", r->number);
71 if (previous_lhs != r->lhs)
fd7f0289 72 fprintf (out, "%s:", r->lhs->tag);
ce4ccb4b 73 else
fd7f0289 74 fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), "");
ce4ccb4b
AD
75}
76
41d7a5f2 77void
510c8497 78rule_lhs_print_xml (rule const *r, FILE *out, int level)
41d7a5f2
PE
79{
80 xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
81}
82
08c81469 83size_t
510c8497 84rule_rhs_length (rule const *r)
c3b407f4 85{
08c81469 86 size_t res = 0;
81ebdef9
PE
87 item_number *rhsp;
88 for (rhsp = r->rhs; *rhsp >= 0; ++rhsp)
c3b407f4
AD
89 ++res;
90 return res;
91}
92
6b98e4b5 93void
510c8497 94rule_rhs_print (rule const *r, FILE *out)
6b98e4b5 95{
81ebdef9 96 if (*r->rhs >= 0)
6b98e4b5 97 {
81ebdef9
PE
98 item_number *rp;
99 for (rp = r->rhs; *rp >= 0; rp++)
e9690142 100 fprintf (out, " %s", symbols[*rp]->tag);
6b98e4b5
AD
101 }
102 else
103 {
3e153163 104 fprintf (out, " /* %s */", _("empty"));
6b98e4b5
AD
105 }
106}
107
41d7a5f2 108static void
510c8497 109rule_rhs_print_xml (rule const *r, FILE *out, int level)
41d7a5f2
PE
110{
111 if (*r->rhs >= 0)
112 {
113 item_number *rp;
114 xml_puts (out, level, "<rhs>");
115 for (rp = r->rhs; *rp >= 0; rp++)
e9690142
JD
116 xml_printf (out, level + 1, "<symbol>%s</symbol>",
117 xml_escape (symbols[*rp]->tag));
41d7a5f2
PE
118 xml_puts (out, level, "</rhs>");
119 }
120 else
121 {
122 xml_puts (out, level, "<rhs>");
123 xml_puts (out, level + 1, "<empty/>");
124 xml_puts (out, level, "</rhs>");
125 }
126}
6b98e4b5 127
3e153163 128static void
510c8497 129rule_print (rule const *r, FILE *out)
6b98e4b5 130{
81ebdef9
PE
131 fprintf (out, "%s:", r->lhs->tag);
132 rule_rhs_print (r, out);
6b98e4b5
AD
133}
134
cbbe7505 135void
3067fbef 136ritem_print (FILE *out)
f7d4d87a 137{
0c2d3f4c 138 unsigned int i;
3067fbef 139 fputs ("RITEM\n", out);
75142d45
AD
140 for (i = 0; i < nritems; ++i)
141 if (ritem[i] >= 0)
97650f4e 142 fprintf (out, " %s", symbols[ritem[i]]->tag);
3067fbef 143 else
4b3d3a8e 144 fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i]));
3067fbef 145 fputs ("\n\n", out);
f7d4d87a 146}
c2713865 147
c2713865
AD
148size_t
149ritem_longest_rhs (void)
150{
c3b407f4 151 int max = 0;
81ebdef9 152 rule_number r;
c2713865 153
4b3d3a8e 154 for (r = 0; r < nrules; ++r)
c3b407f4 155 {
9222837b 156 int length = rule_rhs_length (&rules[r]);
c3b407f4 157 if (length > max)
e9690142 158 max = length;
c3b407f4 159 }
c2713865
AD
160
161 return max;
162}
78ab8f67 163
6b98e4b5 164void
9757c359 165grammar_rules_partial_print (FILE *out, const char *title,
e9690142 166 rule_filter filter)
6b98e4b5 167{
a737b216 168 rule_number r;
637c4b28 169 bool first = true;
81ebdef9 170 symbol *previous_lhs = NULL;
6b98e4b5
AD
171
172 /* rule # : LHS -> RHS */
c8f002c7 173 for (r = 0; r < nrules + nuseless_productions; r++)
6b98e4b5 174 {
c8f002c7 175 if (filter && !filter (&rules[r]))
e9690142 176 continue;
c8f002c7 177 if (first)
e9690142 178 fprintf (out, "%s\n\n", title);
c8f002c7 179 else if (previous_lhs && previous_lhs != rules[r].lhs)
e9690142 180 fputc ('\n', out);
637c4b28 181 first = false;
ce4ccb4b 182 rule_lhs_print (&rules[r], previous_lhs, out);
6b98e4b5 183 rule_rhs_print (&rules[r], out);
3e153163 184 fprintf (out, "\n");
ce4ccb4b 185 previous_lhs = rules[r].lhs;
6b98e4b5 186 }
c8f002c7
AD
187 if (!first)
188 fputs ("\n\n", out);
6b98e4b5
AD
189}
190
41d7a5f2 191void
d80fb37a
JD
192grammar_rules_print (FILE *out)
193{
194 grammar_rules_partial_print (out, _("Grammar"), rule_useful_in_grammar_p);
195}
196
197void
198grammar_rules_print_xml (FILE *out, int level)
41d7a5f2
PE
199{
200 rule_number r;
201 bool first = true;
202
203 for (r = 0; r < nrules + nuseless_productions; r++)
204 {
d80fb37a 205 if (first)
e9690142 206 xml_puts (out, level + 1, "<rules>");
41d7a5f2 207 first = false;
d80fb37a
JD
208 {
209 char const *usefulness;
210 if (rule_useless_in_grammar_p (&rules[r]))
211 usefulness = "useless-in-grammar";
212 else if (rule_useless_in_parser_p (&rules[r]))
213 usefulness = "useless-in-parser";
214 else
215 usefulness = "useful";
408476bc
JD
216 xml_indent (out, level + 2);
217 fprintf (out, "<rule number=\"%d\" usefulness=\"%s\"",
218 rules[r].number, usefulness);
219 if (rules[r].precsym)
44bb9084
AD
220 fprintf (out, " percent_prec=\"%s\"",
221 xml_escape (rules[r].precsym->tag));
408476bc 222 fputs (">\n", out);
d80fb37a 223 }
41d7a5f2
PE
224 rule_lhs_print_xml (&rules[r], out, level + 3);
225 rule_rhs_print_xml (&rules[r], out, level + 3);
226 xml_puts (out, level + 2, "</rule>");
227 }
d80fb37a
JD
228 if (!first)
229 xml_puts (out, level + 1, "</rules>");
230 else
231 xml_puts (out, level + 1, "<rules/>");
41d7a5f2
PE
232}
233
78ab8f67
AD
234void
235grammar_dump (FILE *out, const char *title)
236{
78ab8f67
AD
237 fprintf (out, "%s\n\n", title);
238 fprintf (out,
e9690142
JD
239 "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
240 ntokens, nvars, nsyms, nrules, nritems);
9222837b
AD
241
242
2f4f028d 243 fprintf (out, "Variables\n---------\n\n");
9222837b 244 {
81ebdef9 245 symbol_number i;
2f4f028d
PE
246 fprintf (out, "Value Sprec Sassoc Tag\n");
247
9222837b
AD
248 for (i = ntokens; i < nsyms; i++)
249 fprintf (out, "%5d %5d %5d %s\n",
e9690142
JD
250 i,
251 symbols[i]->prec, symbols[i]->assoc,
252 symbols[i]->tag);
2f4f028d 253 fprintf (out, "\n\n");
9222837b
AD
254 }
255
2f4f028d 256 fprintf (out, "Rules\n-----\n\n");
9222837b 257 {
81ebdef9 258 rule_number i;
510c8497
AD
259 fprintf (out,
260 "Num (Prec, Assoc, Useful, Ritem Range) Lhs"
261 " -> Rhs (Ritem range) [Num]\n");
4b3d3a8e 262 for (i = 0; i < nrules + nuseless_productions; i++)
9222837b 263 {
510c8497 264 rule const *rule_i = &rules[i];
e9690142
JD
265 item_number *rp = NULL;
266 unsigned int rhs_itemno = rule_i->rhs - ritem;
267 unsigned int rhs_count = 0;
268 /* Find the last RHS index in ritems. */
269 for (rp = rule_i->rhs; *rp >= 0; ++rp)
270 ++rhs_count;
271 fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
272 i,
273 rule_i->prec ? rule_i->prec->prec : 0,
274 rule_i->prec ? rule_i->prec->assoc : 0,
275 rule_i->useful,
276 rhs_itemno,
277 rhs_itemno + rhs_count - 1,
278 rule_i->lhs->number);
279 /* Dumped the RHS. */
280 for (rp = rule_i->rhs; *rp >= 0; rp++)
281 fprintf (out, " %3d", *rp);
282 fprintf (out, " [%d]\n", item_number_as_rule_number (*rp));
9222837b
AD
283 }
284 }
2f4f028d 285 fprintf (out, "\n\n");
9222837b 286
2f4f028d 287 fprintf (out, "Rules interpreted\n-----------------\n\n");
9222837b 288 {
81ebdef9 289 rule_number r;
4b3d3a8e 290 for (r = 0; r < nrules + nuseless_productions; r++)
9222837b 291 {
e9690142
JD
292 fprintf (out, "%-5d ", r);
293 rule_print (&rules[r], out);
3e153163 294 fprintf (out, "\n");
9222837b
AD
295 }
296 }
2f4f028d 297 fprintf (out, "\n\n");
78ab8f67 298}
5372019f 299
c8f002c7 300void
cff03fb2 301grammar_rules_useless_report (const char *message)
c8f002c7 302{
5ff5cf67
VS
303 warnings w = Wother;
304 if (warnings_flag & w)
305 {
306 rule_number r;
307 for (r = 0; r < nrules ; ++r)
308 if (!rules[r].useful)
c39014ae 309 {
f3ead217
TR
310 if (feature_flag & feature_caret)
311 complain (&rules[r].location, w, "%s", message);
312 else
3f5d1b2c 313 {
f3ead217 314 complain (&rules[r].location, w | silent, "%s: ", message);
3f5d1b2c 315 rule_print (&rules[r], stderr);
f3ead217
TR
316 warnings_print_categories (w);
317 fprintf (stderr, "\n");
3f5d1b2c 318 }
c39014ae 319 }
3e153163 320 }
c8f002c7
AD
321}
322
5372019f
AD
323void
324grammar_free (void)
325{
e9ad4aec
PE
326 if (ritem)
327 free (ritem - 1);
4b3d3a8e 328 free (rules);
afbb696d 329 free (token_translations);
5372019f
AD
330 /* Free the symbol table data structure. */
331 symbols_free ();
676385e2 332 free_merger_functions ();
5372019f 333}