]> git.saurik.com Git - bison.git/blame - src/gram.c
Remaining m4sugar merge from autoconf.
[bison.git] / src / gram.c
CommitLineData
6f84e9ab
PE
1/* Allocate input grammar variables for Bison.
2
41d7a5f2
PE
3 Copyright (C) 1984, 1986, 1989, 2001, 2002, 2003, 2005, 2006
4 2007 Free Software 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
PE
23
24#include <quotearg.h>
25
78ab8f67 26#include "gram.h"
3067fbef 27#include "reader.h"
81ebdef9
PE
28#include "reduce.h"
29#include "symtab.h"
41d7a5f2 30#include "print-xml.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)
ce4ccb4b
AD
79 fputc (' ', out);
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
c3b407f4 90int
81ebdef9 91rule_rhs_length (rule *r)
c3b407f4
AD
92{
93 int 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++)
107 fprintf (out, " %s", symbols[*rp]->tag);
6b98e4b5
AD
108 fputc ('\n', out);
109 }
110 else
111 {
112 fprintf (out, " /* %s */\n", _("empty"));
113 }
114}
115
41d7a5f2
PE
116static void
117rule_rhs_print_xml (rule *r, FILE *out, int level)
118{
119 if (*r->rhs >= 0)
120 {
121 item_number *rp;
122 xml_puts (out, level, "<rhs>");
123 for (rp = r->rhs; *rp >= 0; rp++)
408476bc 124 xml_printf (out, level + 1, "<symbol>%s</symbol>",
41d7a5f2
PE
125 xml_escape (symbols[*rp]->tag));
126 xml_puts (out, level, "</rhs>");
127 }
128 else
129 {
130 xml_puts (out, level, "<rhs>");
131 xml_puts (out, level + 1, "<empty/>");
132 xml_puts (out, level, "</rhs>");
133 }
134}
6b98e4b5 135
6b98e4b5 136void
81ebdef9 137rule_print (rule *r, FILE *out)
6b98e4b5 138{
81ebdef9
PE
139 fprintf (out, "%s:", r->lhs->tag);
140 rule_rhs_print (r, out);
6b98e4b5
AD
141}
142
cbbe7505 143void
3067fbef 144ritem_print (FILE *out)
f7d4d87a 145{
0c2d3f4c 146 unsigned int i;
3067fbef 147 fputs ("RITEM\n", out);
75142d45
AD
148 for (i = 0; i < nritems; ++i)
149 if (ritem[i] >= 0)
97650f4e 150 fprintf (out, " %s", symbols[ritem[i]]->tag);
3067fbef 151 else
4b3d3a8e 152 fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i]));
3067fbef 153 fputs ("\n\n", out);
f7d4d87a 154}
c2713865 155
c2713865
AD
156size_t
157ritem_longest_rhs (void)
158{
c3b407f4 159 int max = 0;
81ebdef9 160 rule_number r;
c2713865 161
4b3d3a8e 162 for (r = 0; r < nrules; ++r)
c3b407f4 163 {
9222837b 164 int length = rule_rhs_length (&rules[r]);
c3b407f4
AD
165 if (length > max)
166 max = length;
167 }
c2713865
AD
168
169 return max;
170}
78ab8f67 171
6b98e4b5 172void
9757c359 173grammar_rules_partial_print (FILE *out, const char *title,
81ebdef9 174 rule_filter filter)
6b98e4b5 175{
a737b216 176 rule_number r;
637c4b28 177 bool first = true;
81ebdef9 178 symbol *previous_lhs = NULL;
6b98e4b5
AD
179
180 /* rule # : LHS -> RHS */
c8f002c7 181 for (r = 0; r < nrules + nuseless_productions; r++)
6b98e4b5 182 {
c8f002c7
AD
183 if (filter && !filter (&rules[r]))
184 continue;
185 if (first)
186 fprintf (out, "%s\n\n", title);
187 else if (previous_lhs && previous_lhs != rules[r].lhs)
6b98e4b5 188 fputc ('\n', out);
637c4b28 189 first = false;
ce4ccb4b 190 rule_lhs_print (&rules[r], previous_lhs, out);
6b98e4b5 191 rule_rhs_print (&rules[r], out);
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)
41d7a5f2
PE
213 xml_puts (out, level + 1, "<rules>");
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)
227 fprintf (out, " percent_prec=\"%s\"", rules[r].precsym->tag);
228 fputs (">\n", out);
d80fb37a 229 }
41d7a5f2
PE
230 rule_lhs_print_xml (&rules[r], out, level + 3);
231 rule_rhs_print_xml (&rules[r], out, level + 3);
232 xml_puts (out, level + 2, "</rule>");
233 }
d80fb37a
JD
234 if (!first)
235 xml_puts (out, level + 1, "</rules>");
236 else
237 xml_puts (out, level + 1, "<rules/>");
41d7a5f2
PE
238}
239
78ab8f67
AD
240void
241grammar_dump (FILE *out, const char *title)
242{
78ab8f67
AD
243 fprintf (out, "%s\n\n", title);
244 fprintf (out,
245 "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
246 ntokens, nvars, nsyms, nrules, nritems);
9222837b
AD
247
248
2f4f028d 249 fprintf (out, "Variables\n---------\n\n");
9222837b 250 {
81ebdef9 251 symbol_number i;
2f4f028d
PE
252 fprintf (out, "Value Sprec Sassoc Tag\n");
253
9222837b
AD
254 for (i = ntokens; i < nsyms; i++)
255 fprintf (out, "%5d %5d %5d %s\n",
256 i,
257 symbols[i]->prec, symbols[i]->assoc,
97650f4e 258 symbols[i]->tag);
2f4f028d 259 fprintf (out, "\n\n");
9222837b
AD
260 }
261
2f4f028d 262 fprintf (out, "Rules\n-----\n\n");
9222837b 263 {
81ebdef9 264 rule_number i;
2f4f028d 265 fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
4b3d3a8e 266 for (i = 0; i < nrules + nuseless_productions; i++)
9222837b 267 {
81ebdef9 268 rule *rule_i = &rules[i];
a737b216 269 item_number *rp = NULL;
81ebdef9 270 unsigned int rhs_itemno = rule_i->rhs - ritem;
04098407 271 unsigned int rhs_count = 0;
9222837b 272 /* Find the last RHS index in ritems. */
a737b216 273 for (rp = rule_i->rhs; *rp >= 0; ++rp)
9222837b 274 ++rhs_count;
e3fbd37f 275 fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
4b3d3a8e 276 i,
81ebdef9
PE
277 rule_i->prec ? rule_i->prec->prec : 0,
278 rule_i->prec ? rule_i->prec->assoc : 0,
279 rule_i->useful,
e3fbd37f
PE
280 rhs_itemno,
281 rhs_itemno + rhs_count - 1,
81ebdef9 282 rule_i->lhs->number);
9222837b 283 /* Dumped the RHS. */
a737b216
PE
284 for (rp = rule_i->rhs; *rp >= 0; rp++)
285 fprintf (out, " %3d", *rp);
286 fprintf (out, " [%d]\n", item_number_as_rule_number (*rp));
9222837b
AD
287 }
288 }
2f4f028d 289 fprintf (out, "\n\n");
9222837b 290
2f4f028d 291 fprintf (out, "Rules interpreted\n-----------------\n\n");
9222837b 292 {
81ebdef9 293 rule_number r;
4b3d3a8e 294 for (r = 0; r < nrules + nuseless_productions; r++)
9222837b
AD
295 {
296 fprintf (out, "%-5d ", r);
297 rule_print (&rules[r], out);
298 }
299 }
2f4f028d 300 fprintf (out, "\n\n");
78ab8f67 301}
5372019f 302
c8f002c7 303void
cff03fb2 304grammar_rules_useless_report (const char *message)
c8f002c7 305{
81ebdef9 306 rule_number r;
c8f002c7
AD
307 for (r = 0; r < nrules ; ++r)
308 if (!rules[r].useful)
309 {
5fcdb07b 310 location_print (stderr, rules[r].location);
affac613 311 fprintf (stderr, ": %s: %s: ", _("warning"), message);
c8f002c7
AD
312 rule_print (&rules[r], stderr);
313 }
314}
315
5372019f
AD
316void
317grammar_free (void)
318{
e9ad4aec
PE
319 if (ritem)
320 free (ritem - 1);
4b3d3a8e 321 free (rules);
afbb696d 322 free (token_translations);
5372019f
AD
323 /* Free the symbol table data structure. */
324 symbols_free ();
676385e2 325 free_merger_functions ();
5372019f 326}