]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
maint: run "make update-copyright"
[bison.git] / src / reader.c
index ce23f48c9c8c5263b5a9b83b8d3761a672cb114a..19b1044b8bbbc6068ad0a6de25823f96b9474198 100644 (file)
@@ -1,24 +1,22 @@
 /* Input parser for Bison
 
-   Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002, 2003,
-   2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000-2003, 2005-2007,
+   2009-2010 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
-   Bison is free software; you can redistribute it and/or modify
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bison is distributed in the hope that it will be useful,
+   This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with Bison; see the file COPYING.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "system.h"
@@ -69,27 +67,6 @@ grammar_start_symbol_set (symbol *sym, location loc)
     }
 }
 
-
-/*---------------------------------------------------------------------.
-| There are two prologues: one before the first %union and one after.  |
-| Augment the one specified by POST.                                   |
-`---------------------------------------------------------------------*/
-
-void
-prologue_augment (const char *prologue, location loc, bool post)
-{
-  struct obstack *oout =
-    !post ? &pre_prologue_obstack : &post_prologue_obstack;
-
-  obstack_fgrow1 (oout, "]b4_syncline(%d, [[", loc.start.line);
-  /* FIXME: Protection of M4 characters missing here.  See
-     output.c:escaped_output.  */
-  MUSCLE_OBSTACK_SGROW (oout,
-                       quotearg_style (c_quoting_style, loc.start.file));
-  obstack_sgrow (oout, "]])[\n");
-  obstack_sgrow (oout, prologue);
-}
-
 \f
 
 /*------------------------------------------------------------------------.
@@ -253,21 +230,14 @@ grammar_current_rule_begin (symbol *lhs, location loc)
 static bool
 symbol_should_be_used (symbol_list const *s)
 {
-  if (code_props_code_get (symbol_destructor_get (s->content.sym)))
+  if (symbol_destructor_get (s->content.sym)->code)
     return true;
   if (warnings_flag & warnings_midrule_values)
-    {
-      if (s->midrule && code_props_is_value_used (s->midrule->action_props))
-        return true;
-      if (s->midrule_parent_rule)
-        {
-          symbol_list *rhs_node =
-            symbol_list_n_get (s->midrule_parent_rule,
-                               s->midrule_parent_rhs_index);
-          if (code_props_is_value_used (rhs_node->action_props))
-            return true;
-        }
-    }
+    return ((s->midrule && s->midrule->action_props.is_value_used)
+           || (s->midrule_parent_rule
+               && symbol_list_n_get (s->midrule_parent_rule,
+                                     s->midrule_parent_rhs_index)
+                     ->action_props.is_value_used));
   return false;
 }
 
@@ -286,7 +256,7 @@ grammar_rule_check (const symbol_list *r)
 
      Don't worry about the default action if $$ is untyped, since $$'s
      value can't be used.  */
-  if (!code_props_code_get (r->action_props) && r->content.sym->type_name)
+  if (!r->action_props.code && r->content.sym->type_name)
     {
       symbol *first_rhs = r->next->content.sym;
       /* If $$ is being set in default way, report if any type mismatch.  */
@@ -311,11 +281,10 @@ grammar_rule_check (const symbol_list *r)
     symbol_list const *l = r;
     int n = 0;
     for (; l && l->content.sym; l = l->next, ++n)
-      if (! (code_props_is_value_used (l->action_props)
+      if (! (l->action_props.is_value_used
             || !symbol_should_be_used (l)
             /* The default action, $$ = $1, `uses' both.  */
-            || (!code_props_code_get (r->action_props)
-                 && (n == 0 || n == 1))))
+            || (!r->action_props.code && (n == 0 || n == 1))))
        {
          if (n)
            warn_at (r->location, _("unused value: $%d"), n);
@@ -323,6 +292,15 @@ grammar_rule_check (const symbol_list *r)
            warn_at (r->location, _("unset value: $$"));
        }
   }
+
+  /* See comments in grammar_current_rule_prec_set for how POSIX
+     mandates this complaint.  It's only for identifiers, so skip
+     it for char literals and strings, which are always tokens.  */
+  if (r->ruleprec
+      && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
+      && !r->ruleprec->declared && !r->ruleprec->prec)
+    warn_at (r->location, _("token for %%prec is not defined: %s"),
+             r->ruleprec->tag);
 }
 
 
@@ -355,8 +333,7 @@ grammar_midrule_action (void)
 
   /* Make a DUMMY nonterminal, whose location is that of the midrule
      action.  Create the MIDRULE.  */
-  location dummy_location =
-    code_props_location_get (current_rule->action_props);
+  location dummy_location = current_rule->action_props.location;
   symbol *dummy = dummy_symbol_get (dummy_location);
   symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
 
@@ -366,11 +343,10 @@ grammar_midrule_action (void)
   ++nritems;
   /* Attach its location and actions to that of the DUMMY.  */
   midrule->location = dummy_location;
-  code_props_rule_action_init (
-    &midrule->action_props,
-    code_props_code_get (current_rule->action_props),
-    code_props_location_get (current_rule->action_props),
-    midrule);
+  code_props_rule_action_init (&midrule->action_props,
+                               current_rule->action_props.code,
+                               current_rule->action_props.location,
+                               midrule);
   code_props_none_init (&current_rule->action_props);
 
   if (previous_rule_end)
@@ -397,6 +373,17 @@ grammar_midrule_action (void)
 void
 grammar_current_rule_prec_set (symbol *precsym, location loc)
 {
+  /* POSIX says that any identifier is a nonterminal if it does not
+     appear on the LHS of a grammar rule and is not defined by %token
+     or by one of the directives that assigns precedence to a token.  We
+     ignore this here because the only kind of identifier that POSIX
+     allows to follow a %prec is a token and because assuming it's a
+     token now can produce more logical error messages.  Nevertheless,
+     grammar_rule_check does obey what we believe is the real intent of
+     POSIX here: that an error be reported for any identifier that
+     appears after %prec but that is not defined separately as a
+     token.  */
+  symbol_class_set (precsym, token_sym, loc, false);
   if (current_rule->ruleprec)
     complain_at (loc, _("only one %s allowed per rule"), "%prec");
   current_rule->ruleprec = precsym;
@@ -436,7 +423,7 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
 void
 grammar_current_rule_symbol_append (symbol *sym, location loc)
 {
-  if (code_props_code_get (current_rule->action_props))
+  if (current_rule->action_props.code)
     grammar_midrule_action ();
   grammar_symbol_append (sym, loc);
 }
@@ -446,7 +433,7 @@ grammar_current_rule_symbol_append (symbol *sym, location loc)
 void
 grammar_current_rule_action_append (const char *action, location loc)
 {
-  if (code_props_code_get (current_rule->action_props))
+  if (current_rule->action_props.code)
     grammar_midrule_action ();
   /* After all symbol declarations have been parsed, packgram invokes
      code_props_translate_code.  */
@@ -474,20 +461,6 @@ packgram (void)
 
   rules = xnmalloc (nrules, sizeof *rules);
 
-  /* Before invoking grammar_rule_check on any rule, make sure all actions have
-     already been scanned in order to set `used' flags.  Otherwise, checking
-     that a midrule's $$ should be set will not always work properly because
-     the check must forward-reference the midrule's parent rule.  For the same
-     reason, all the `used' flags must be set before checking whether to remove
-     `$' from any midrule symbol name.  */
-  while (p)
-    {
-      code_props_translate_code (&p->action_props);
-      if (p)
-       p = p->next;
-    }
-
-  p = grammar;
   while (p)
     {
       int rule_length = 0;
@@ -504,20 +477,17 @@ packgram (void)
       rules[ruleno].precsym = NULL;
       rules[ruleno].location = p->location;
       rules[ruleno].useful = true;
-      rules[ruleno].action = code_props_code_get (p->action_props);
-      if (rules[ruleno].action)
-        rules[ruleno].action_location =
-          code_props_location_get (p->action_props);
+      rules[ruleno].action = p->action_props.code;
+      rules[ruleno].action_location = p->action_props.location;
 
       /* If the midrule's $$ is set or its $n is used, remove the `$' from the
         symbol name so that it's a user-defined symbol so that the default
         %destructor and %printer apply.  */
       if (p->midrule_parent_rule
-          && (code_props_is_value_used (p->action_props)
-             || code_props_is_value_used (
-                  symbol_list_n_get (
-                    p->midrule_parent_rule,
-                    p->midrule_parent_rhs_index)->action_props)))
+          && (p->action_props.is_value_used
+             || symbol_list_n_get (p->midrule_parent_rule,
+                                   p->midrule_parent_rhs_index)
+                   ->action_props.is_value_used))
        p->content.sym->tag += 1;
 
       /* Don't check the generated rule 0.  It has no action, so some rhs
@@ -597,10 +567,6 @@ reader (void)
   undeftoken->class = token_sym;
   undeftoken->number = ntokens++;
 
-  /* Initialize the obstacks. */
-  obstack_init (&pre_prologue_obstack);
-  obstack_init (&post_prologue_obstack);
-
   gram_in = xfopen (grammar_file, "r");
 
   gram__flex_debug = trace_flag & trace_scan;
@@ -680,6 +646,23 @@ check_and_convert_grammar (void)
      token symbols into FDEFINES if requested.  */
   symbols_pack ();
 
+  /* Scan rule actions after invoking symbol_check_alias_consistency (in
+     symbols_pack above) so that token types are set correctly before the rule
+     action type checking.
+
+     Before invoking grammar_rule_check (in packgram below) on any rule, make
+     sure all actions have already been scanned in order to set `used' flags.
+     Otherwise, checking that a midrule's $$ should be set will not always work
+     properly because the check must forward-reference the midrule's parent
+     rule.  For the same reason, all the `used' flags must be set before
+     checking whether to remove `$' from any midrule symbol name (also in
+     packgram).  */
+  {
+    symbol_list *sym;
+    for (sym = grammar; sym; sym = sym->next)
+      code_props_translate_code (&sym->action_props);
+  }
+
   /* Convert the grammar into the format described in gram.h.  */
   packgram ();