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