]> git.saurik.com Git - bison.git/blame - src/gram.c
* data/bison.m4 (b4_cat): Put a newline after the end delimiter of the
[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
AD
49/*--------------------------------------------------------------.
50| Return true IFF the rule has a `number' smaller than NRULES. |
51`--------------------------------------------------------------*/
52
53bool
81ebdef9 54rule_useful_p (rule *r)
c8f002c7
AD
55{
56 return r->number < nrules;
57}
58
59
60/*-------------------------------------------------------------.
61| Return true IFF the rule has a `number' higher than NRULES. |
62`-------------------------------------------------------------*/
63
64bool
81ebdef9 65rule_useless_p (rule *r)
c8f002c7 66{
affac613 67 return !rule_useful_p (r);
c8f002c7
AD
68}
69
70
71/*--------------------------------------------------------------------.
72| Return true IFF the rule is not flagged as useful *and* is useful. |
73| In other words, it was discarded because of conflicts. |
74`--------------------------------------------------------------------*/
75
76bool
81ebdef9 77rule_never_reduced_p (rule *r)
c8f002c7 78{
affac613 79 return !r->useful && rule_useful_p (r);
c8f002c7
AD
80}
81
82
ce4ccb4b
AD
83/*----------------------------------------------------------------.
84| Print this RULE's number and lhs on OUT. If a PREVIOUS_LHS was |
85| already displayed (by a previous call for another rule), avoid |
86| useless repetitions. |
87`----------------------------------------------------------------*/
88
89void
81ebdef9 90rule_lhs_print (rule *r, symbol *previous_lhs, FILE *out)
ce4ccb4b 91{
81ebdef9
PE
92 fprintf (out, " %3d ", r->number);
93 if (previous_lhs != r->lhs)
ce4ccb4b 94 {
81ebdef9 95 fprintf (out, "%s:", r->lhs->tag);
ce4ccb4b
AD
96 }
97 else
98 {
99 int n;
97650f4e 100 for (n = strlen (previous_lhs->tag); n > 0; --n)
ce4ccb4b
AD
101 fputc (' ', out);
102 fputc ('|', out);
103 }
104}
105
41d7a5f2
PE
106void
107rule_lhs_print_xml (rule *r, FILE *out, int level)
108{
109 xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
110}
111
ce4ccb4b 112
c3b407f4
AD
113/*--------------------------------------.
114| Return the number of symbols in RHS. |
115`--------------------------------------*/
116
117int
81ebdef9 118rule_rhs_length (rule *r)
c3b407f4
AD
119{
120 int res = 0;
81ebdef9
PE
121 item_number *rhsp;
122 for (rhsp = r->rhs; *rhsp >= 0; ++rhsp)
c3b407f4
AD
123 ++res;
124 return res;
125}
126
127
6b98e4b5 128/*-------------------------------.
81ebdef9 129| Print this rule's RHS on OUT. |
6b98e4b5
AD
130`-------------------------------*/
131
132void
81ebdef9 133rule_rhs_print (rule *r, FILE *out)
6b98e4b5 134{
81ebdef9 135 if (*r->rhs >= 0)
6b98e4b5 136 {
81ebdef9
PE
137 item_number *rp;
138 for (rp = r->rhs; *rp >= 0; rp++)
139 fprintf (out, " %s", symbols[*rp]->tag);
6b98e4b5
AD
140 fputc ('\n', out);
141 }
142 else
143 {
144 fprintf (out, " /* %s */\n", _("empty"));
145 }
146}
147
41d7a5f2
PE
148static void
149rule_rhs_print_xml (rule *r, FILE *out, int level)
150{
151 if (*r->rhs >= 0)
152 {
153 item_number *rp;
154 xml_puts (out, level, "<rhs>");
155 for (rp = r->rhs; *rp >= 0; rp++)
156 xml_printf (out, level + 1, "<symbol class=\"%s\">%s</symbol>",
157 symbol_class_get_string (symbols[*rp]),
158 xml_escape (symbols[*rp]->tag));
159 xml_puts (out, level, "</rhs>");
160 }
161 else
162 {
163 xml_puts (out, level, "<rhs>");
164 xml_puts (out, level + 1, "<empty/>");
165 xml_puts (out, level, "</rhs>");
166 }
167}
6b98e4b5
AD
168
169/*-------------------------.
81ebdef9 170| Print this rule on OUT. |
6b98e4b5
AD
171`-------------------------*/
172
173void
81ebdef9 174rule_print (rule *r, FILE *out)
6b98e4b5 175{
81ebdef9
PE
176 fprintf (out, "%s:", r->lhs->tag);
177 rule_rhs_print (r, out);
6b98e4b5
AD
178}
179
180
c2713865
AD
181/*------------------------.
182| Dump RITEM for traces. |
183`------------------------*/
184
cbbe7505 185void
3067fbef 186ritem_print (FILE *out)
f7d4d87a 187{
0c2d3f4c 188 unsigned int i;
3067fbef 189 fputs ("RITEM\n", out);
75142d45
AD
190 for (i = 0; i < nritems; ++i)
191 if (ritem[i] >= 0)
97650f4e 192 fprintf (out, " %s", symbols[ritem[i]]->tag);
3067fbef 193 else
4b3d3a8e 194 fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i]));
3067fbef 195 fputs ("\n\n", out);
f7d4d87a 196}
c2713865
AD
197
198
199/*------------------------------------------.
200| Return the size of the longest rule RHS. |
201`------------------------------------------*/
202
203size_t
204ritem_longest_rhs (void)
205{
c3b407f4 206 int max = 0;
81ebdef9 207 rule_number r;
c2713865 208
4b3d3a8e 209 for (r = 0; r < nrules; ++r)
c3b407f4 210 {
9222837b 211 int length = rule_rhs_length (&rules[r]);
c3b407f4
AD
212 if (length > max)
213 max = length;
214 }
c2713865
AD
215
216 return max;
217}
78ab8f67
AD
218
219
c8f002c7
AD
220/*-----------------------------------------------------------------.
221| Print the grammar's rules that match FILTER on OUT under TITLE. |
222`-----------------------------------------------------------------*/
6b98e4b5 223
6b98e4b5 224void
9757c359 225grammar_rules_partial_print (FILE *out, const char *title,
81ebdef9 226 rule_filter filter)
6b98e4b5 227{
a737b216 228 rule_number r;
637c4b28 229 bool first = true;
81ebdef9 230 symbol *previous_lhs = NULL;
6b98e4b5
AD
231
232 /* rule # : LHS -> RHS */
c8f002c7 233 for (r = 0; r < nrules + nuseless_productions; r++)
6b98e4b5 234 {
c8f002c7
AD
235 if (filter && !filter (&rules[r]))
236 continue;
237 if (first)
238 fprintf (out, "%s\n\n", title);
239 else if (previous_lhs && previous_lhs != rules[r].lhs)
6b98e4b5 240 fputc ('\n', out);
637c4b28 241 first = false;
ce4ccb4b 242 rule_lhs_print (&rules[r], previous_lhs, out);
6b98e4b5 243 rule_rhs_print (&rules[r], out);
ce4ccb4b 244 previous_lhs = rules[r].lhs;
6b98e4b5 245 }
c8f002c7
AD
246 if (!first)
247 fputs ("\n\n", out);
6b98e4b5
AD
248}
249
9757c359 250
41d7a5f2
PE
251/*----------------------------------------------------------.
252| Print the grammar's rules that match FILTER on OUT (XML). |
253`-----------------------------------------------------------*/
254
255void
256grammar_rules_partial_print_xml (FILE *out, int level, bool rtag,
257 rule_filter filter)
258{
259 rule_number r;
260 bool first = true;
261
262 for (r = 0; r < nrules + nuseless_productions; r++)
263 {
264 if (filter && !filter (&rules[r]))
265 continue;
266 if (rtag && first)
267 xml_puts (out, level + 1, "<rules>");
268 first = false;
269
270 xml_printf (out, level + 2, "<rule number=\"%d\">",
271 rules[r].number);
272 rule_lhs_print_xml (&rules[r], out, level + 3);
273 rule_rhs_print_xml (&rules[r], out, level + 3);
274 xml_puts (out, level + 2, "</rule>");
275 }
276 if (rtag)
277 {
278 if (!first)
279 xml_puts (out, level + 1, "</rules>");
280 else
281 xml_puts (out, level + 1, "<rules/>");
282 }
283}
284
9757c359
AD
285/*------------------------------------------.
286| Print the grammar's useful rules on OUT. |
287`------------------------------------------*/
288
289void
290grammar_rules_print (FILE *out)
291{
c8f002c7 292 grammar_rules_partial_print (out, _("Grammar"), rule_useful_p);
9757c359
AD
293}
294
41d7a5f2
PE
295void
296grammar_rules_print_xml (FILE *out, int level)
297{
298 grammar_rules_partial_print_xml (out, level, true, rule_useful_p);
299}
300
9757c359 301
78ab8f67
AD
302/*-------------------.
303| Dump the grammar. |
304`-------------------*/
305
306void
307grammar_dump (FILE *out, const char *title)
308{
78ab8f67
AD
309 fprintf (out, "%s\n\n", title);
310 fprintf (out,
311 "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
312 ntokens, nvars, nsyms, nrules, nritems);
9222837b
AD
313
314
2f4f028d 315 fprintf (out, "Variables\n---------\n\n");
9222837b 316 {
81ebdef9 317 symbol_number i;
2f4f028d
PE
318 fprintf (out, "Value Sprec Sassoc Tag\n");
319
9222837b
AD
320 for (i = ntokens; i < nsyms; i++)
321 fprintf (out, "%5d %5d %5d %s\n",
322 i,
323 symbols[i]->prec, symbols[i]->assoc,
97650f4e 324 symbols[i]->tag);
2f4f028d 325 fprintf (out, "\n\n");
9222837b
AD
326 }
327
2f4f028d 328 fprintf (out, "Rules\n-----\n\n");
9222837b 329 {
81ebdef9 330 rule_number i;
2f4f028d 331 fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n");
4b3d3a8e 332 for (i = 0; i < nrules + nuseless_productions; i++)
9222837b 333 {
81ebdef9 334 rule *rule_i = &rules[i];
a737b216 335 item_number *rp = NULL;
81ebdef9 336 unsigned int rhs_itemno = rule_i->rhs - ritem;
04098407 337 unsigned int rhs_count = 0;
9222837b 338 /* Find the last RHS index in ritems. */
a737b216 339 for (rp = rule_i->rhs; *rp >= 0; ++rp)
9222837b 340 ++rhs_count;
e3fbd37f 341 fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
4b3d3a8e 342 i,
81ebdef9
PE
343 rule_i->prec ? rule_i->prec->prec : 0,
344 rule_i->prec ? rule_i->prec->assoc : 0,
345 rule_i->useful,
e3fbd37f
PE
346 rhs_itemno,
347 rhs_itemno + rhs_count - 1,
81ebdef9 348 rule_i->lhs->number);
9222837b 349 /* Dumped the RHS. */
a737b216
PE
350 for (rp = rule_i->rhs; *rp >= 0; rp++)
351 fprintf (out, " %3d", *rp);
352 fprintf (out, " [%d]\n", item_number_as_rule_number (*rp));
9222837b
AD
353 }
354 }
2f4f028d 355 fprintf (out, "\n\n");
9222837b 356
2f4f028d 357 fprintf (out, "Rules interpreted\n-----------------\n\n");
9222837b 358 {
81ebdef9 359 rule_number r;
4b3d3a8e 360 for (r = 0; r < nrules + nuseless_productions; r++)
9222837b
AD
361 {
362 fprintf (out, "%-5d ", r);
363 rule_print (&rules[r], out);
364 }
365 }
2f4f028d 366 fprintf (out, "\n\n");
78ab8f67 367}
5372019f
AD
368
369
c8f002c7
AD
370/*------------------------------------------------------------------.
371| Report on STDERR the rules that are not flagged USEFUL, using the |
372| MESSAGE (which can be `useless rule' when invoked after grammar |
373| reduction, or `never reduced' after conflicts were taken into |
374| account). |
375`------------------------------------------------------------------*/
376
377void
378grammar_rules_never_reduced_report (const char *message)
379{
81ebdef9 380 rule_number r;
c8f002c7
AD
381 for (r = 0; r < nrules ; ++r)
382 if (!rules[r].useful)
383 {
5fcdb07b 384 location_print (stderr, rules[r].location);
affac613 385 fprintf (stderr, ": %s: %s: ", _("warning"), message);
c8f002c7
AD
386 rule_print (&rules[r], stderr);
387 }
388}
389
5372019f
AD
390void
391grammar_free (void)
392{
e9ad4aec
PE
393 if (ritem)
394 free (ritem - 1);
4b3d3a8e 395 free (rules);
afbb696d 396 free (token_translations);
5372019f
AD
397 /* Free the symbol table data structure. */
398 symbols_free ();
676385e2 399 free_merger_functions ();
5372019f 400}