Home | History | Annotate | Download | only in src
      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