]> git.saurik.com Git - bison.git/blame - src/gram.c
Merge branch 'maint'
[bison.git] / src / gram.c
CommitLineData
6f84e9ab
PE
1/* Allocate input grammar variables for Bison.
2
34136e65 3 Copyright (C) 1984, 1986, 1989, 2001-2003, 2005-2012 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
cff03fb2 50rule_useful_in_grammar_p (rule *r)
c8f002c7
AD
51{
52 return r->number < nrules;
53}
54
c8f002c7 55bool
cff03fb2 56rule_useless_in_grammar_p (rule *r)
c8f002c7 57{
cff03fb2 58 return !rule_useful_in_grammar_p (r);
c8f002c7
AD
59}
60
c8f002c7 61bool
cff03fb2 62rule_useless_in_parser_p (rule *r)
c8f002c7 63{
cff03fb2 64 return !r->useful && rule_useful_in_grammar_p (r);
c8f002c7
AD
65}
66
ce4ccb4b 67void
81ebdef9 68rule_lhs_print (rule *r, symbol *previous_lhs, FILE *out)
ce4ccb4b 69{
81ebdef9
PE
70 fprintf (out, " %3d ", r->number);
71 if (previous_lhs != r->lhs)
ce4ccb4b 72 {
81ebdef9 73 fprintf (out, "%s:", r->lhs->tag);
ce4ccb4b
AD
74 }
75 else
76 {
77 int n;
97650f4e 78 for (n = strlen (previous_lhs->tag); n > 0; --n)
e9690142 79 fputc (' ', out);
ce4ccb4b
AD
80 fputc ('|', out);
81 }
82}
83
41d7a5f2
PE
84void
85rule_lhs_print_xml (rule *r, FILE *out, int level)
86{
87 xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
88}
89
08c81469 90size_t
81ebdef9 91rule_rhs_length (rule *r)
c3b407f4 92{
08c81469 93 size_t res = 0;
81ebdef9
PE
94 item_number *rhsp;
95 for (rhsp = r->rhs; *rhsp >= 0; ++rhsp)
c3b407f4
AD
96 ++res;
97 return res;
98}
99
6b98e4b5 100void
81ebdef9 101rule_rhs_print (rule *r, FILE *out)
6b98e4b5 102{
81ebdef9 103 if (*r->rhs >= 0)
6b98e4b5 104 {
81ebdef9
PE
105 item_number *rp;
106 for (rp = r->rhs; *rp >= 0; rp++)
e9690142 107 fprintf (out, " %s", symbols[*rp]->tag);
6b98e4b5
AD
108 }
109 else
110 {
3e153163 111 fprintf (out, " /* %s */", _("empty"));
6b98e4b5
AD
112 }
113}
114
41d7a5f2
PE
115static void
116rule_rhs_print_xml (rule *r, FILE *out, int level)
117{
118 if (*r->rhs >= 0)
119 {
120 item_number *rp;
121 xml_puts (out, level, "<rhs>");
122 for (rp = r->rhs; *rp >= 0; rp++)
e9690142
JD
123 xml_printf (out, level + 1, "<symbol>%s</symbol>",
124 xml_escape (symbols[*rp]->tag));
41d7a5f2
PE
125 xml_puts (out, level, "</rhs>");
126 }
127 else
128 {
129 xml_puts (out, level, "<rhs>");
130 xml_puts (out, level + 1, "<empty/>");
131 xml_puts (out, level, "</rhs>");
132 }
133}
6b98e4b5 134
3e153163 135static void
81ebdef9 136rule_print (rule *r, FILE *out)
6b98e4b5 137{
81ebdef9
PE
138 fprintf (out, "%s:", r->lhs->tag);
139 rule_rhs_print (r, out);
6b98e4b5
AD
140}
141
cbbe7505 142void
3067fbef 143ritem_print (FILE *out)
f7d4d87a 144{
0c2d3f4c 145 unsigned int i;
3067fbef 146 fputs ("RITEM\n", out);
75142d45
AD
147 for (i = 0; i < nritems; ++i)
148 if (ritem[i] >= 0)
97650f4e 149 fprintf (out, " %s", symbols[ritem[i]]->tag);
3067fbef 150 else
4b3d3a8e 151 fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i]));
3067fbef 152 fputs ("\n\n", out);
f7d4d87a 153}
c2713865 154
c2713865
AD
155size_t
156ritem_longest_rhs (void)
157{
c3b407f4 158 int max = 0;
81ebdef9 159 rule_number r;
c2713865 160
4b3d3a8e 161 for (r = 0; r < nrules; ++r)
c3b407f4 162 {
9222837b 163 int length = rule_rhs_length (&rules[r]);
c3b407f4 164 if (length > max)
e9690142 165 max = length;
c3b407f4 166 }
c2713865
AD
167
168 return max;
169}
78ab8f67 170
6b98e4b5 171void
9757c359 172grammar_rules_partial_print (FILE *out, const char *title,
e9690142 173 rule_filter filter)
6b98e4b5 174{
a737b216 175 rule_number r;
637c4b28 176 bool first = true;
81ebdef9 177 symbol *previous_lhs = NULL;
6b98e4b5
AD
178
179 /* rule # : LHS -> RHS */
c8f002c7 180 for (r = 0; r < nrules + nuseless_productions; r++)
6b98e4b5 181 {
c8f002c7 182 if (filter && !filter (&rules[r]))
e9690142 183 continue;
c8f002c7 184 if (first)
e9690142 185 fprintf (out, "%s\n\n", title);
c8f002c7 186 else if (previous_lhs && previous_lhs != rules[r].lhs)
e9690142 187 fputc ('\n', out);
637c4b28 188 first = false;
ce4ccb4b 189 rule_lhs_print (&rules[r], previous_lhs, out);
6b98e4b5 190 rule_rhs_print (&rules[r], out);
3e153163 191 fprintf (out, "\n");
ce4ccb4b 192 previous_lhs = rules[r].lhs;
6b98e4b5 193 }
c8f002c7
AD
194 if (!first)
195 fputs ("\n\n", out);
6b98e4b5
AD
196}
197
41d7a5f2 198void
d80fb37a
JD
199grammar_rules_print (FILE *out)
200{
201 grammar_rules_partial_print (out, _("Grammar"), rule_useful_in_grammar_p);
202}
203
204void
205grammar_rules_print_xml (FILE *out, int level)
41d7a5f2
PE
206{
207 rule_number r;
208 bool first = true;
209
210 for (r = 0; r < nrules + nuseless_productions; r++)
211 {
d80fb37a 212 if (first)
e9690142 213 xml_puts (out, level + 1, "<rules>");
41d7a5f2 214 first = false;
d80fb37a
JD
215 {
216 char const *usefulness;
217 if (rule_useless_in_grammar_p (&rules[r]))
218 usefulness = "useless-in-grammar";
219 else if (rule_useless_in_parser_p (&rules[r]))
220 usefulness = "useless-in-parser";
221 else
222 usefulness = "useful";
408476bc
JD
223 xml_indent (out, level + 2);
224 fprintf (out, "<rule number=\"%d\" usefulness=\"%s\"",
225 rules[r].number, usefulness);
226 if (rules[r].precsym)
44bb9084
AD
227 fprintf (out, " percent_prec=\"%s\"",
228 xml_escape (rules[r].precsym->tag));
408476bc 229 fputs (">\n", out);
d80fb37a 230 }
41d7a5f2
PE
231 rule_lhs_print_xml (&rules[r], out, level + 3);
232 rule_rhs_print_xml (&rules[r], out, level + 3);
233 xml_puts (out, level + 2, "</rule>");
234 }
d80fb37a
JD
235 if (!first)
236 xml_puts (out, level + 1, "</rules>");
237 else
238 xml_puts (out, level + 1, "<rules/>");
41d7a5f2
PE
239}
240
78ab8f67
AD
241void
242grammar_dump (FILE *out, const char *title)
243{
78ab8f67
AD
244 fprintf (out, "%s\n\n", title);
245 fprintf (out,
e9690142
JD
246 "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
247 ntokens, nvars, nsyms, nrules, nritems);
9222837b
AD
248
249
2f4f028d 250 fprintf (out, "Variables\n---------\n\n");
9222837b 251 {
81ebdef9 252 symbol_number i;
2f4f028d
PE
253 fprintf (out, "Value Sprec Sassoc Tag\n");
254
9222837b
AD
255 for (i = ntokens; i < nsyms; i++)
256 fprintf (out, "%5d %5d %5d %s\n",
e9690142
JD
257 i,
258 symbols[i]->prec, symbols[i]->assoc,
259 symbols[i]->tag);
2f4f028d 260 fprintf (out, "\n\n");
9222837b
AD
261 }
262
2f4f028d 263 fprintf (out, "Rules\n-----\n\n");
9222837b 264 {
81ebdef9 265 rule_number i;
2f4f028d 266 fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
4b3d3a8e 267 for (i = 0; i < nrules + nuseless_productions; i++)
9222837b 268 {
e9690142
JD
269 rule *rule_i = &rules[i];
270 item_number *rp = NULL;
271 unsigned int rhs_itemno = rule_i->rhs - ritem;
272 unsigned int rhs_count = 0;
273 /* Find the last RHS index in ritems. */
274 for (rp = rule_i->rhs; *rp >= 0; ++rp)
275 ++rhs_count;
276 fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
277 i,
278 rule_i->prec ? rule_i->prec->prec : 0,
279 rule_i->prec ? rule_i->prec->assoc : 0,
280 rule_i->useful,
281 rhs_itemno,
282 rhs_itemno + rhs_count - 1,
283 rule_i->lhs->number);
284 /* Dumped the RHS. */
285 for (rp = rule_i->rhs; *rp >= 0; rp++)
286 fprintf (out, " %3d", *rp);
287 fprintf (out, " [%d]\n", item_number_as_rule_number (*rp));
9222837b
AD
288 }
289 }
2f4f028d 290 fprintf (out, "\n\n");
9222837b 291
2f4f028d 292 fprintf (out, "Rules interpreted\n-----------------\n\n");
9222837b 293 {
81ebdef9 294 rule_number r;
4b3d3a8e 295 for (r = 0; r < nrules + nuseless_productions; r++)
9222837b 296 {
e9690142
JD
297 fprintf (out, "%-5d ", r);
298 rule_print (&rules[r], out);
3e153163 299 fprintf (out, "\n");
9222837b
AD
300 }
301 }
2f4f028d 302 fprintf (out, "\n\n");
78ab8f67 303}
5372019f 304
c8f002c7 305void
cff03fb2 306grammar_rules_useless_report (const char *message)
c8f002c7 307{
5ff5cf67
VS
308 warnings w = Wother;
309 if (warnings_flag & w)
310 {
311 rule_number r;
312 for (r = 0; r < nrules ; ++r)
313 if (!rules[r].useful)
c39014ae 314 {
bb8e56ff 315 complain (&rules[r].location, w | silent, "%s: ", message);
c39014ae 316 rule_print (&rules[r], stderr);
73370a9d 317 warnings_print_categories (w);
3e153163 318 fprintf (stderr, "\n");
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}