]> git.saurik.com Git - bison.git/commitdiff
* src/reader.c (grammar_current_rule_prec_set).
authorAkim Demaille <akim@epita.fr>
Tue, 11 Jun 2002 08:08:22 +0000 (08:08 +0000)
committerAkim Demaille <akim@epita.fr>
Tue, 11 Jun 2002 08:08:22 +0000 (08:08 +0000)
(grammar_current_rule_check): New, eved out from...
(readgram): here.
Remove `xaction', `first_rhs': useless.
* tests/input.at (Type clashes): New.
* tests/existing.at (GNU Cim Grammar): Adjust.

ChangeLog
NEWS
src/reader.c
tests/existing.at
tests/input.at

index 300da61b41a961fefa2aa9f01b2c98ea8a190eb7..4c99aa2302acbd5c43d6dddac4b26d4593bb2222 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2002-06-11  Akim Demaille  <akim@epita.fr>
+
+       * src/reader.c (grammar_current_rule_prec_set).
+       (grammar_current_rule_check): New, eved out from...
+       (readgram): here.
+       Remove `xaction', `first_rhs': useless.
+       * tests/input.at (Type clashes): New.
+       * tests/existing.at (GNU Cim Grammar): Adjust.
+
 2002-06-11  Akim Demaille  <akim@epita.fr>
 
        * src/reader.c (grammar_midrule_action): New, Eved out from
 2002-06-11  Akim Demaille  <akim@epita.fr>
 
        * src/reader.c (grammar_midrule_action): New, Eved out from
diff --git a/NEWS b/NEWS
index e4acf388f9a024bc14ff4a802d1a2bc69c5bdd94..64258f23752c46f941e11eedb1b4aa9434630390 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -96,6 +96,15 @@ Changes in version 1.49b:
     Bison used to systematically output this information on top of
     the report.  Solved conflicts are now attached to their states.
 
     Bison used to systematically output this information on top of
     the report.  Solved conflicts are now attached to their states.
 
+* Type clashes
+  Previous versions don't complain when there is a type clash on
+  the default action if the rule has a mid-rule action, such as in:
+
+      %type <foo> bar
+      %%
+      bar: '0' {} '0';
+
+  This is fixed.
 \f
 Changes in version 1.35, 2002-03-25:
 
 \f
 Changes in version 1.35, 2002-03-25:
 
index 949d74bb26cc657d2b3ebe09e64631c8fff05232..42a48ee787a7070d3114164647f14cd6382537cb 100644 (file)
@@ -972,8 +972,6 @@ read_declarations (void)
 | which says where to find `$0' with respect to the top of the      |
 | stack.  It is not the same as the rule->length in the case of mid |
 | rule actions.                                                     |
 | which says where to find `$0' with respect to the top of the      |
 | stack.  It is not the same as the rule->length in the case of mid |
 | rule actions.                                                     |
-|                                                                   |
-| This routine is used for actions.                                 |
 `------------------------------------------------------------------*/
 
 static void
 `------------------------------------------------------------------*/
 
 static void
@@ -1169,6 +1167,48 @@ grammar_midrule_action (void)
   grammar_symbol_append (sdummy);
 }
 
   grammar_symbol_append (sdummy);
 }
 
+/* Set the precedence symbol of the current rule to PRECSYM. */
+
+static void
+grammar_current_rule_prec_set (symbol_t *precsym)
+{
+  if (current_rule->ruleprec)
+    complain (_("two @prec's in a row"));
+  current_rule->ruleprec = precsym;
+}
+
+/* Check that the last rule (CURRENT_RULE) is properly defined.  For
+   instance, there should be no type clash on the default action.  */
+
+static void
+grammar_current_rule_check (void)
+{
+  symbol_t *lhs = current_rule->sym;
+  symbol_t *first_rhs = current_rule->next->sym;
+
+  /* If there is an action, then there is nothing we can do: the user
+     is allowed to shoot in her foot.  */
+  if (current_rule->action)
+    return;
+
+  /* If $$ is being set in default way, report if any type mismatch.
+     */
+  if (first_rhs)
+    {
+      const char *lhs_type = lhs->type_name       ? lhs->type_name       : "";
+      const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : "";
+      if (strcmp (lhs_type, rhs_type))
+       complain (_("type clash (`%s' `%s') on default action"),
+                 lhs_type, rhs_type);
+    }
+  /* Warn if there is no default for $$ but we need one.  */
+  else
+    {
+      if (lhs->type_name)
+       complain (_("empty rule for typed nonterminal, and no action"));
+    }
+}
+
 
 static void
 readgram (void)
 
 static void
 readgram (void)
@@ -1184,8 +1224,6 @@ readgram (void)
        int action_flag = 0;
        /* Number of symbols in rhs of this rule so far */
        int rulelength = 0;
        int action_flag = 0;
        /* Number of symbols in rhs of this rule so far */
        int rulelength = 0;
-       int xactions = 0;       /* JF for error checking */
-       symbol_t *first_rhs = 0;
 
        if (t == tok_identifier)
          {
 
        if (t == tok_identifier)
          {
@@ -1213,7 +1251,7 @@ readgram (void)
            if (t == tok_prec)
              {
                t = lex ();
            if (t == tok_prec)
              {
                t = lex ();
-               current_rule->ruleprec = symval;
+               grammar_current_rule_prec_set (symval);
                t = lex ();
              }
 
                t = lex ();
              }
 
@@ -1236,11 +1274,8 @@ readgram (void)
                    warn (_("previous rule lacks an ending `;'"));
                    break;
                  }
                    warn (_("previous rule lacks an ending `;'"));
                    break;
                  }
-
-               if (!first_rhs) /* JF */
-                 first_rhs = symval;
-               /* Not followed by colon =>
-                  process as part of this rule's rhs.  */
+               /* Not followed by colon => process as part of this
+                  rule's rhs.  */
              }
 
            /* If we just passed an action, that action was in the middle
              }
 
            /* If we just passed an action, that action was in the middle
@@ -1261,7 +1296,6 @@ readgram (void)
              {
                parse_action (current_rule, rulelength);
                action_flag = 1;
              {
                parse_action (current_rule, rulelength);
                action_flag = 1;
-               ++xactions;     /* JF */
              }
            ++rulelength;
          }                     /* end of  read rhs of rule */
              }
            ++rulelength;
          }                     /* end of  read rhs of rule */
@@ -1271,37 +1305,20 @@ readgram (void)
 
        if (t == tok_prec)
          {
 
        if (t == tok_prec)
          {
-           complain (_("two @prec's in a row"));
            t = lex ();
            t = lex ();
-           current_rule->ruleprec = symval;
+           grammar_current_rule_prec_set (symval);
            t = lex ();
          }
 
        if (t == tok_left_curly)
          {
            t = lex ();
          }
 
        if (t == tok_left_curly)
          {
-           /* This case never occurs -wjh */
-           if (action_flag)
-             complain (_("two actions at end of one rule"));
            parse_action (current_rule, rulelength);
            action_flag = 1;
            parse_action (current_rule, rulelength);
            action_flag = 1;
-           ++xactions; /* -wjh */
            t = lex ();
          }
            t = lex ();
          }
-       /* If $$ is being set in default way, report if any type
-          mismatch.  */
-       else if (!xactions
-                && first_rhs && lhs->type_name != first_rhs->type_name)
-         {
-           if (lhs->type_name == 0
-               || first_rhs->type_name == 0
-               || strcmp (lhs->type_name, first_rhs->type_name))
-             complain (_("type clash (`%s' `%s') on default action"),
-                       lhs->type_name ? lhs->type_name : "",
-                       first_rhs->type_name ? first_rhs->type_name : "");
-         }
-       /* Warn if there is no default for $$ but we need one.  */
-       else if (!xactions && !first_rhs && lhs->type_name != 0)
-         complain (_("empty rule for typed nonterminal, and no action"));
+
+       grammar_current_rule_check ();
+
        if (t == tok_two_percents || t == tok_eof)
          warn (_("previous rule lacks an ending `;'"));
        if (t == tok_semicolon)
        if (t == tok_two_percents || t == tok_eof)
          warn (_("previous rule lacks an ending `;'"));
        if (t == tok_semicolon)
index 3f6612f7ba3bfe4f28ac9c6c1873873ecf49c710..6a1f7f39236af022ca5c80e446ea780542df5852 100644 (file)
@@ -907,7 +907,7 @@ MBEE_LISTV      :       /*EMPT*/
 LISTV           :       HIDENTIFIER     { regDecl($1, type, KNOKD, CDEFLT);}
                 |      FPP_CATEG HDOTDOTDOT      { regDecl(varargsid, TVARARGS, KNOKD, categ);}
                 |       HIDENTIFIER     { regDecl($1, type, KNOKD, CDEFLT);}
 LISTV           :       HIDENTIFIER     { regDecl($1, type, KNOKD, CDEFLT);}
                 |      FPP_CATEG HDOTDOTDOT      { regDecl(varargsid, TVARARGS, KNOKD, categ);}
                 |       HIDENTIFIER     { regDecl($1, type, KNOKD, CDEFLT);}
-                        HPAREXPSEPARATOR LISTV
+                        HPAREXPSEPARATOR LISTV {}
                 |       FPP_SPEC
                 |       FPP_SPEC
                         HPAREXPSEPARATOR LISTV
                 |       FPP_SPEC
                 |       FPP_SPEC
                         HPAREXPSEPARATOR LISTV
@@ -947,7 +947,7 @@ FPP_PROC_DECL_IN_SPEC:      MBEE_TYPE HPROCEDURE
 IDENTIFIER_LISTV:       HIDENTIFIER     { regDecl($1, type, kind, categ);}
                 |      HDOTDOTDOT {      regDecl(varargsid, TVARARGS, kind, categ);}
                 |       HIDENTIFIER     { regDecl($1, type, kind, categ);}
 IDENTIFIER_LISTV:       HIDENTIFIER     { regDecl($1, type, kind, categ);}
                 |      HDOTDOTDOT {      regDecl(varargsid, TVARARGS, kind, categ);}
                 |       HIDENTIFIER     { regDecl($1, type, kind, categ);}
-                        HPAREXPSEPARATOR IDENTIFIER_LISTV
+                        HPAREXPSEPARATOR IDENTIFIER_LISTV {}
                 ;
 MBEE_MODE_PART  :       /*EMPT*/
                 |       MODE_PART
                 ;
 MBEE_MODE_PART  :       /*EMPT*/
                 |       MODE_PART
@@ -1153,7 +1153,7 @@ EXPRESSION_SIMP : EXPRESSION_SIMP
                 |       HNONE                   { mout(MNONE);$$=NULL;}
                 |       HIDENTIFIER
                                 { $<ident>$=$1;}
                 |       HNONE                   { mout(MNONE);$$=NULL;}
                 |       HIDENTIFIER
                                 { $<ident>$=$1;}
-                        MBEE_ARG_R_PT
+                        MBEE_ARG_R_PT {}
                 |       HTHIS HIDENTIFIER       { mout(MTHIS);
                                                   moutId($2);$$=NULL;}
                 |       HNEW
                 |       HTHIS HIDENTIFIER       { mout(MTHIS);
                                                   moutId($2);$$=NULL;}
                 |       HNEW
index 2ee59f29f7b9cd7166209e040415db6eb536e50e..9c223d37555e06e5735f8dcf9c9bfbfb42ec8871 100644 (file)
@@ -24,7 +24,6 @@ AT_BANNER([[Input Processing.]])
 ## Invalid $n.  ##
 ## ------------ ##
 
 ## Invalid $n.  ##
 ## ------------ ##
 
-
 AT_SETUP([Invalid $n])
 
 AT_DATA([input.y],
 AT_SETUP([Invalid $n])
 
 AT_DATA([input.y],
@@ -43,7 +42,6 @@ AT_CLEANUP
 ## Invalid @n.  ##
 ## ------------ ##
 
 ## Invalid @n.  ##
 ## ------------ ##
 
-
 AT_SETUP([Invalid @n])
 
 AT_DATA([input.y],
 AT_SETUP([Invalid @n])
 
 AT_DATA([input.y],
@@ -56,3 +54,28 @@ AT_CHECK([bison input.y], [1], [],
 ]])
 
 AT_CLEANUP
 ]])
 
 AT_CLEANUP
+
+
+## -------------- ##
+## Type clashes.  ##
+## -------------- ##
+
+AT_SETUP([Type clashes])
+
+AT_DATA([input.y],
+[[%token foo
+%type <bar> exp
+%%
+exp: foo {} foo
+   | foo
+   | /* Empty. */
+   ;
+]])
+
+AT_CHECK([bison input.y], [1], [],
+[[input.y:5: type clash (`bar' `') on default action
+input.y:6: type clash (`bar' `') on default action
+input.y:7: empty rule for typed nonterminal, and no action
+]])
+
+AT_CLEANUP