]> git.saurik.com Git - bison.git/blame - src/gram.c
portability: fix spawning on at least FreeBSD 8 and FreeBSD 9.
[bison.git] / src / gram.c
CommitLineData
6f84e9ab
PE
1/* Allocate input grammar variables for Bison.
2
e141f4d4
JD
3 Copyright (C) 1984, 1986, 1989, 2001-2003, 2005-2010 Free Software
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
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
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++)
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)
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,
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",
257 i,
258 symbols[i]->prec, symbols[i]->assoc,
97650f4e 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 {
81ebdef9 269 rule *rule_i = &rules[i];
a737b216 270 item_number *rp = NULL;
81ebdef9 271 unsigned int rhs_itemno = rule_i->rhs - ritem;
04098407 272 unsigned int rhs_count = 0;
9222837b 273 /* Find the last RHS index in ritems. */
a737b216 274 for (rp = rule_i->rhs; *rp >= 0; ++rp)
9222837b 275 ++rhs_count;
e3fbd37f 276 fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
4b3d3a8e 277 i,
81ebdef9
PE
278 rule_i->prec ? rule_i->prec->prec : 0,
279 rule_i->prec ? rule_i->prec->assoc : 0,
280 rule_i->useful,
e3fbd37f
PE
281 rhs_itemno,
282 rhs_itemno + rhs_count - 1,
81ebdef9 283 rule_i->lhs->number);
9222837b 284 /* Dumped the RHS. */
a737b216
PE
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
AD
296 {
297 fprintf (out, "%-5d ", r);
298 rule_print (&rules[r], out);
299 }
300 }
2f4f028d 301 fprintf (out, "\n\n");
78ab8f67 302}
5372019f 303
c8f002c7 304void
cff03fb2 305grammar_rules_useless_report (const char *message)
c8f002c7 306{
81ebdef9 307 rule_number r;
c8f002c7
AD
308 for (r = 0; r < nrules ; ++r)
309 if (!rules[r].useful)
310 {
5fcdb07b 311 location_print (stderr, rules[r].location);
affac613 312 fprintf (stderr, ": %s: %s: ", _("warning"), message);
c8f002c7
AD
313 rule_print (&rules[r], stderr);
314 }
315}
316
5372019f
AD
317void
318grammar_free (void)
319{
e9ad4aec
PE
320 if (ritem)
321 free (ritem - 1);
4b3d3a8e 322 free (rules);
afbb696d 323 free (token_translations);
5372019f
AD
324 /* Free the symbol table data structure. */
325 symbols_free ();
676385e2 326 free_merger_functions ();
5372019f 327}