]> git.saurik.com Git - bison.git/blame - src/gram.c
Merge remote-tracking branch 'origin/maint'
[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{
8b807f11 96 if (0 <= *r->rhs)
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
8b807f11 103 fputs (" %empty", out);
6b98e4b5
AD
104}
105
41d7a5f2 106static void
510c8497 107rule_rhs_print_xml (rule const *r, FILE *out, int level)
41d7a5f2
PE
108{
109 if (*r->rhs >= 0)
110 {
111 item_number *rp;
112 xml_puts (out, level, "<rhs>");
113 for (rp = r->rhs; *rp >= 0; rp++)
e9690142
JD
114 xml_printf (out, level + 1, "<symbol>%s</symbol>",
115 xml_escape (symbols[*rp]->tag));
41d7a5f2
PE
116 xml_puts (out, level, "</rhs>");
117 }
118 else
119 {
120 xml_puts (out, level, "<rhs>");
121 xml_puts (out, level + 1, "<empty/>");
122 xml_puts (out, level, "</rhs>");
123 }
124}
6b98e4b5 125
cbbe7505 126void
3067fbef 127ritem_print (FILE *out)
f7d4d87a 128{
0c2d3f4c 129 unsigned int i;
3067fbef 130 fputs ("RITEM\n", out);
75142d45
AD
131 for (i = 0; i < nritems; ++i)
132 if (ritem[i] >= 0)
97650f4e 133 fprintf (out, " %s", symbols[ritem[i]]->tag);
3067fbef 134 else
4b3d3a8e 135 fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i]));
3067fbef 136 fputs ("\n\n", out);
f7d4d87a 137}
c2713865 138
c2713865
AD
139size_t
140ritem_longest_rhs (void)
141{
c3b407f4 142 int max = 0;
81ebdef9 143 rule_number r;
c2713865 144
4b3d3a8e 145 for (r = 0; r < nrules; ++r)
c3b407f4 146 {
9222837b 147 int length = rule_rhs_length (&rules[r]);
c3b407f4 148 if (length > max)
e9690142 149 max = length;
c3b407f4 150 }
c2713865
AD
151
152 return max;
153}
78ab8f67 154
6b98e4b5 155void
9757c359 156grammar_rules_partial_print (FILE *out, const char *title,
e9690142 157 rule_filter filter)
6b98e4b5 158{
a737b216 159 rule_number r;
637c4b28 160 bool first = true;
81ebdef9 161 symbol *previous_lhs = NULL;
6b98e4b5
AD
162
163 /* rule # : LHS -> RHS */
c8f002c7 164 for (r = 0; r < nrules + nuseless_productions; r++)
6b98e4b5 165 {
c8f002c7 166 if (filter && !filter (&rules[r]))
e9690142 167 continue;
c8f002c7 168 if (first)
e9690142 169 fprintf (out, "%s\n\n", title);
c8f002c7 170 else if (previous_lhs && previous_lhs != rules[r].lhs)
e9690142 171 fputc ('\n', out);
637c4b28 172 first = false;
ce4ccb4b 173 rule_lhs_print (&rules[r], previous_lhs, out);
6b98e4b5 174 rule_rhs_print (&rules[r], out);
3e153163 175 fprintf (out, "\n");
ce4ccb4b 176 previous_lhs = rules[r].lhs;
6b98e4b5 177 }
c8f002c7
AD
178 if (!first)
179 fputs ("\n\n", out);
6b98e4b5
AD
180}
181
41d7a5f2 182void
d80fb37a
JD
183grammar_rules_print (FILE *out)
184{
185 grammar_rules_partial_print (out, _("Grammar"), rule_useful_in_grammar_p);
186}
187
188void
189grammar_rules_print_xml (FILE *out, int level)
41d7a5f2
PE
190{
191 rule_number r;
192 bool first = true;
193
194 for (r = 0; r < nrules + nuseless_productions; r++)
195 {
d80fb37a 196 if (first)
e9690142 197 xml_puts (out, level + 1, "<rules>");
41d7a5f2 198 first = false;
d80fb37a
JD
199 {
200 char const *usefulness;
201 if (rule_useless_in_grammar_p (&rules[r]))
202 usefulness = "useless-in-grammar";
203 else if (rule_useless_in_parser_p (&rules[r]))
204 usefulness = "useless-in-parser";
205 else
206 usefulness = "useful";
408476bc
JD
207 xml_indent (out, level + 2);
208 fprintf (out, "<rule number=\"%d\" usefulness=\"%s\"",
209 rules[r].number, usefulness);
210 if (rules[r].precsym)
44bb9084
AD
211 fprintf (out, " percent_prec=\"%s\"",
212 xml_escape (rules[r].precsym->tag));
408476bc 213 fputs (">\n", out);
d80fb37a 214 }
41d7a5f2
PE
215 rule_lhs_print_xml (&rules[r], out, level + 3);
216 rule_rhs_print_xml (&rules[r], out, level + 3);
217 xml_puts (out, level + 2, "</rule>");
218 }
d80fb37a
JD
219 if (!first)
220 xml_puts (out, level + 1, "</rules>");
221 else
222 xml_puts (out, level + 1, "<rules/>");
41d7a5f2
PE
223}
224
78ab8f67
AD
225void
226grammar_dump (FILE *out, const char *title)
227{
78ab8f67
AD
228 fprintf (out, "%s\n\n", title);
229 fprintf (out,
e9690142
JD
230 "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
231 ntokens, nvars, nsyms, nrules, nritems);
9222837b
AD
232
233
2f4f028d 234 fprintf (out, "Variables\n---------\n\n");
9222837b 235 {
81ebdef9 236 symbol_number i;
2f4f028d
PE
237 fprintf (out, "Value Sprec Sassoc Tag\n");
238
9222837b
AD
239 for (i = ntokens; i < nsyms; i++)
240 fprintf (out, "%5d %5d %5d %s\n",
e9690142
JD
241 i,
242 symbols[i]->prec, symbols[i]->assoc,
243 symbols[i]->tag);
2f4f028d 244 fprintf (out, "\n\n");
9222837b
AD
245 }
246
2f4f028d 247 fprintf (out, "Rules\n-----\n\n");
9222837b 248 {
81ebdef9 249 rule_number i;
510c8497
AD
250 fprintf (out,
251 "Num (Prec, Assoc, Useful, Ritem Range) Lhs"
252 " -> Rhs (Ritem range) [Num]\n");
4b3d3a8e 253 for (i = 0; i < nrules + nuseless_productions; i++)
9222837b 254 {
510c8497 255 rule const *rule_i = &rules[i];
e9690142
JD
256 item_number *rp = NULL;
257 unsigned int rhs_itemno = rule_i->rhs - ritem;
258 unsigned int rhs_count = 0;
259 /* Find the last RHS index in ritems. */
260 for (rp = rule_i->rhs; *rp >= 0; ++rp)
261 ++rhs_count;
262 fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
263 i,
264 rule_i->prec ? rule_i->prec->prec : 0,
265 rule_i->prec ? rule_i->prec->assoc : 0,
266 rule_i->useful,
267 rhs_itemno,
268 rhs_itemno + rhs_count - 1,
269 rule_i->lhs->number);
270 /* Dumped the RHS. */
271 for (rp = rule_i->rhs; *rp >= 0; rp++)
272 fprintf (out, " %3d", *rp);
273 fprintf (out, " [%d]\n", item_number_as_rule_number (*rp));
9222837b
AD
274 }
275 }
2f4f028d 276 fprintf (out, "\n\n");
9222837b 277
2f4f028d 278 fprintf (out, "Rules interpreted\n-----------------\n\n");
9222837b 279 {
81ebdef9 280 rule_number r;
4b3d3a8e 281 for (r = 0; r < nrules + nuseless_productions; r++)
9222837b 282 {
fec5f3c0
AD
283 fprintf (out, "%-5d %s:", r, rules[r].lhs->tag);
284 rule_rhs_print (&rules[r], out);
3e153163 285 fprintf (out, "\n");
9222837b
AD
286 }
287 }
2f4f028d 288 fprintf (out, "\n\n");
78ab8f67 289}
5372019f 290
c8f002c7 291void
cff03fb2 292grammar_rules_useless_report (const char *message)
c8f002c7 293{
fec5f3c0
AD
294 rule_number r;
295 for (r = 0; r < nrules ; ++r)
296 if (!rules[r].useful)
297 complain (&rules[r].location, Wother, "%s", message);
c8f002c7
AD
298}
299
5372019f
AD
300void
301grammar_free (void)
302{
e9ad4aec
PE
303 if (ritem)
304 free (ritem - 1);
4b3d3a8e 305 free (rules);
afbb696d 306 free (token_translations);
5372019f
AD
307 /* Free the symbol table data structure. */
308 symbols_free ();
676385e2 309 free_merger_functions ();
5372019f 310}