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