1 /* Allocate input grammar variables for Bison. 2 3 Copyright (C) 1984, 1986, 1989, 2001, 2002, 2003, 2005, 2006 Free 4 Software Foundation, Inc. 5 6 This file is part of Bison, the GNU Compiler Compiler. 7 8 Bison is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2, or (at your option) 11 any later version. 12 13 Bison is distributed in the hope that it will be useful, 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. 17 18 You should have received a copy of the GNU General Public License 19 along with Bison; see the file COPYING. If not, write to 20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 Boston, MA 02110-1301, USA. */ 22 23 #include <config.h> 24 #include "system.h" 25 26 #include <quotearg.h> 27 28 #include "gram.h" 29 #include "reader.h" 30 #include "reduce.h" 31 #include "symtab.h" 32 33 /* Comments for these variables are in gram.h. */ 34 35 item_number *ritem = NULL; 36 unsigned int nritems = 0; 37 38 rule *rules = NULL; 39 rule_number nrules = 0; 40 41 symbol **symbols = NULL; 42 int nsyms = 0; 43 int ntokens = 1; 44 int nvars = 0; 45 46 symbol_number *token_translations = NULL; 47 48 int max_user_token_number = 256; 49 50 /*--------------------------------------------------------------. 51 | Return true IFF the rule has a `number' smaller than NRULES. | 52 `--------------------------------------------------------------*/ 53 54 bool 55 rule_useful_p (rule *r) 56 { 57 return r->number < nrules; 58 } 59 60 61 /*-------------------------------------------------------------. 62 | Return true IFF the rule has a `number' higher than NRULES. | 63 `-------------------------------------------------------------*/ 64 65 bool 66 rule_useless_p (rule *r) 67 { 68 return !rule_useful_p (r); 69 } 70 71 72 /*--------------------------------------------------------------------. 73 | Return true IFF the rule is not flagged as useful *and* is useful. | 74 | In other words, it was discarded because of conflicts. | 75 `--------------------------------------------------------------------*/ 76 77 bool 78 rule_never_reduced_p (rule *r) 79 { 80 return !r->useful && rule_useful_p (r); 81 } 82 83 84 /*----------------------------------------------------------------. 85 | Print this RULE's number and lhs on OUT. If a PREVIOUS_LHS was | 86 | already displayed (by a previous call for another rule), avoid | 87 | useless repetitions. | 88 `----------------------------------------------------------------*/ 89 90 void 91 rule_lhs_print (rule *r, symbol *previous_lhs, FILE *out) 92 { 93 fprintf (out, " %3d ", r->number); 94 if (previous_lhs != r->lhs) 95 { 96 fprintf (out, "%s:", r->lhs->tag); 97 } 98 else 99 { 100 int n; 101 for (n = strlen (previous_lhs->tag); n > 0; --n) 102 fputc (' ', out); 103 fputc ('|', out); 104 } 105 } 106 107 108 /*--------------------------------------. 109 | Return the number of symbols in RHS. | 110 `--------------------------------------*/ 111 112 int 113 rule_rhs_length (rule *r) 114 { 115 int res = 0; 116 item_number *rhsp; 117 for (rhsp = r->rhs; *rhsp >= 0; ++rhsp) 118 ++res; 119 return res; 120 } 121 122 123 /*-------------------------------. 124 | Print this rule's RHS on OUT. | 125 `-------------------------------*/ 126 127 void 128 rule_rhs_print (rule *r, FILE *out) 129 { 130 if (*r->rhs >= 0) 131 { 132 item_number *rp; 133 for (rp = r->rhs; *rp >= 0; rp++) 134 fprintf (out, " %s", symbols[*rp]->tag); 135 fputc ('\n', out); 136 } 137 else 138 { 139 fprintf (out, " /* %s */\n", _("empty")); 140 } 141 } 142 143 144 /*-------------------------. 145 | Print this rule on OUT. | 146 `-------------------------*/ 147 148 void 149 rule_print (rule *r, FILE *out) 150 { 151 fprintf (out, "%s:", r->lhs->tag); 152 rule_rhs_print (r, out); 153 } 154 155 156 /*------------------------. 157 | Dump RITEM for traces. | 158 `------------------------*/ 159 160 void 161 ritem_print (FILE *out) 162 { 163 unsigned int i; 164 fputs ("RITEM\n", out); 165 for (i = 0; i < nritems; ++i) 166 if (ritem[i] >= 0) 167 fprintf (out, " %s", symbols[ritem[i]]->tag); 168 else 169 fprintf (out, " (rule %d)\n", item_number_as_rule_number (ritem[i])); 170 fputs ("\n\n", out); 171 } 172 173 174 /*------------------------------------------. 175 | Return the size of the longest rule RHS. | 176 `------------------------------------------*/ 177 178 size_t 179 ritem_longest_rhs (void) 180 { 181 int max = 0; 182 rule_number r; 183 184 for (r = 0; r < nrules; ++r) 185 { 186 int length = rule_rhs_length (&rules[r]); 187 if (length > max) 188 max = length; 189 } 190 191 return max; 192 } 193 194 195 /*-----------------------------------------------------------------. 196 | Print the grammar's rules that match FILTER on OUT under TITLE. | 197 `-----------------------------------------------------------------*/ 198 199 void 200 grammar_rules_partial_print (FILE *out, const char *title, 201 rule_filter filter) 202 { 203 rule_number r; 204 bool first = true; 205 symbol *previous_lhs = NULL; 206 207 /* rule # : LHS -> RHS */ 208 for (r = 0; r < nrules + nuseless_productions; r++) 209 { 210 if (filter && !filter (&rules[r])) 211 continue; 212 if (first) 213 fprintf (out, "%s\n\n", title); 214 else if (previous_lhs && previous_lhs != rules[r].lhs) 215 fputc ('\n', out); 216 first = false; 217 rule_lhs_print (&rules[r], previous_lhs, out); 218 rule_rhs_print (&rules[r], out); 219 previous_lhs = rules[r].lhs; 220 } 221 if (!first) 222 fputs ("\n\n", out); 223 } 224 225 226 /*------------------------------------------. 227 | Print the grammar's useful rules on OUT. | 228 `------------------------------------------*/ 229 230 void 231 grammar_rules_print (FILE *out) 232 { 233 grammar_rules_partial_print (out, _("Grammar"), rule_useful_p); 234 } 235 236 237 /*-------------------. 238 | Dump the grammar. | 239 `-------------------*/ 240 241 void 242 grammar_dump (FILE *out, const char *title) 243 { 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); 248 249 250 fprintf (out, "Variables\n---------\n\n"); 251 { 252 symbol_number i; 253 fprintf (out, "Value Sprec Sassoc Tag\n"); 254 255 for (i = ntokens; i < nsyms; i++) 256 fprintf (out, "%5d %5d %5d %s\n", 257 i, 258 symbols[i]->prec, symbols[i]->assoc, 259 symbols[i]->tag); 260 fprintf (out, "\n\n"); 261 } 262 263 fprintf (out, "Rules\n-----\n\n"); 264 { 265 rule_number i; 266 fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n"); 267 for (i = 0; i < nrules + nuseless_productions; i++) 268 { 269 rule *rule_i = &rules[i]; 270 item_number *rp = NULL; 271 unsigned int rhs_itemno = rule_i->rhs - ritem; 272 unsigned int rhs_count = 0; 273 /* Find the last RHS index in ritems. */ 274 for (rp = rule_i->rhs; *rp >= 0; ++rp) 275 ++rhs_count; 276 fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->", 277 i, 278 rule_i->prec ? rule_i->prec->prec : 0, 279 rule_i->prec ? rule_i->prec->assoc : 0, 280 rule_i->useful, 281 rhs_itemno, 282 rhs_itemno + rhs_count - 1, 283 rule_i->lhs->number); 284 /* Dumped the RHS. */ 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)); 288 } 289 } 290 fprintf (out, "\n\n"); 291 292 fprintf (out, "Rules interpreted\n-----------------\n\n"); 293 { 294 rule_number r; 295 for (r = 0; r < nrules + nuseless_productions; r++) 296 { 297 fprintf (out, "%-5d ", r); 298 rule_print (&rules[r], out); 299 } 300 } 301 fprintf (out, "\n\n"); 302 } 303 304 305 /*------------------------------------------------------------------. 306 | Report on STDERR the rules that are not flagged USEFUL, using the | 307 | MESSAGE (which can be `useless rule' when invoked after grammar | 308 | reduction, or `never reduced' after conflicts were taken into | 309 | account). | 310 `------------------------------------------------------------------*/ 311 312 void 313 grammar_rules_never_reduced_report (const char *message) 314 { 315 rule_number r; 316 for (r = 0; r < nrules ; ++r) 317 if (!rules[r].useful) 318 { 319 location_print (stderr, rules[r].location); 320 fprintf (stderr, ": %s: %s: ", _("warning"), message); 321 rule_print (&rules[r], stderr); 322 } 323 } 324 325 void 326 grammar_free (void) 327 { 328 if (ritem) 329 free (ritem - 1); 330 free (rules); 331 free (token_translations); 332 /* Free the symbol table data structure. */ 333 symbols_free (); 334 free_merger_functions (); 335 } 336