]> git.saurik.com Git - bison.git/commitdiff
Fix bug that mistakes braced code in a declaration in the rules section
authorJoel E. Denny <jdenny@ces.clemson.edu>
Sat, 24 Jun 2006 06:51:27 +0000 (06:51 +0000)
committerJoel E. Denny <jdenny@ces.clemson.edu>
Sat, 24 Jun 2006 06:51:27 +0000 (06:51 +0000)
to be a rule action.  Mentioned at
<http://lists.gnu.org/archive/html/bison-patches/2006-06/msg00105.html>.
* src/scan-gram.l: Move midrule action detection from the start of the
scanning of any braced code to...
* src/parse-gram.y (rhs): ... the parsing of braced code as a rule
action.  For readability, use $2 and @2 rather than the equivalent
global variables.
* tests/regression.at (Braced code in declaration in rules section):
New test to catch the error fixed by the above patch.

Work on code readability some.
* src/scan-code.l (current_rule): Get rid of this misleading and
redundant declaration: it's actually extern'ed in reader.h.
(YY_DECL, code_lex, handle_action_dollar, handle_action_at,
translate_action): Add a rule argument and use it instead of the global
current_rule.
(translate_rule_action): This already receives current_rule through an
argument, so pass it on to translate_action instead of assigning
current_rule to current_rule.
(translate_symbol_action, translate_code): Pass rule = NULL to
translate_action.

ChangeLog
src/parse-gram.c
src/parse-gram.y
src/scan-code.l
src/scan-gram.l
tests/regression.at

index 540f35df8d9064f4e859af3bd6f69b55859937f4..41c6c6efca571ac743274e28461ce0b50a402e6d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2006-06-24  Joel E. Denny  <jdenny@ces.clemson.edu>
+
+       Fix bug that mistakes braced code in a declaration in the rules section
+       to be a rule action.  Mentioned at
+       <http://lists.gnu.org/archive/html/bison-patches/2006-06/msg00105.html>.
+       * src/scan-gram.l: Move midrule action detection from the start of the
+       scanning of any braced code to...
+       * src/parse-gram.y (rhs): ... the parsing of braced code as a rule
+       action.  For readability, use $2 and @2 rather than the equivalent
+       global variables.
+       * tests/regression.at (Braced code in declaration in rules section):
+       New test to catch the error fixed by the above patch.
+
+       Work on code readability some.
+       * src/scan-code.l (current_rule): Get rid of this misleading and
+       redundant declaration: it's actually extern'ed in reader.h.
+       (YY_DECL, code_lex, handle_action_dollar, handle_action_at,
+       translate_action): Add a rule argument and use it instead of the global
+       current_rule.
+       (translate_rule_action): This already receives current_rule through an
+       argument, so pass it on to translate_action instead of assigning
+       current_rule to current_rule.
+       (translate_symbol_action, translate_code): Pass rule = NULL to
+       translate_action.
+
 2006-06-23  Joel E. Denny  <jdenny@ces.clemson.edu>
 
        Rename %before-definitions to %start-header and %after-definitions to
index 0b1738d5d05397bcdae6375c9d1c7f32bed88084..905ae1604223d6653145092ae7109a816d5af4ce 100644 (file)
@@ -654,8 +654,8 @@ static const yytype_uint16 yyrline[] =
      305,   309,   323,   324,   328,   350,   350,   355,   355,   360,
      370,   385,   386,   387,   391,   392,   397,   398,   403,   407,
      412,   418,   424,   435,   436,   445,   446,   452,   453,   454,
-     461,   461,   465,   466,   467,   472,   473,   475,   478,   480,
-     482,   495,   497,   506,   511,   512,   517,   526,   531,   533
+     461,   461,   465,   466,   467,   472,   473,   475,   481,   483,
+     485,   498,   500,   509,   514,   515,   520,   529,   534,   536
 };
 #endif
 
@@ -2173,32 +2173,35 @@ yyreduce:
 
   case 77:
 #line 476 "parse-gram.y"
-    { grammar_current_rule_action_append (gram_last_string,
-                                         gram_last_braced_code_loc); }
+    {
+      if (current_rule && current_rule->action)
+       grammar_midrule_action ();
+      grammar_current_rule_action_append ((yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]));
+    }
     break;
 
   case 78:
-#line 479 "parse-gram.y"
+#line 482 "parse-gram.y"
     { grammar_current_rule_prec_set ((yyvsp[(3) - (3)].symbol), (yylsp[(3) - (3)])); }
     break;
 
   case 79:
-#line 481 "parse-gram.y"
+#line 484 "parse-gram.y"
     { grammar_current_rule_dprec_set ((yyvsp[(3) - (3)].integer), (yylsp[(3) - (3)])); }
     break;
 
   case 80:
-#line 483 "parse-gram.y"
+#line 486 "parse-gram.y"
     { grammar_current_rule_merge_set ((yyvsp[(3) - (3)].uniqstr), (yylsp[(3) - (3)])); }
     break;
 
   case 81:
-#line 496 "parse-gram.y"
+#line 499 "parse-gram.y"
     { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
     break;
 
   case 82:
-#line 498 "parse-gram.y"
+#line 501 "parse-gram.y"
     {
       (yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)]));
       symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false);
@@ -2207,12 +2210,12 @@ yyreduce:
     break;
 
   case 83:
-#line 506 "parse-gram.y"
+#line 509 "parse-gram.y"
     { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
     break;
 
   case 86:
-#line 518 "parse-gram.y"
+#line 521 "parse-gram.y"
     {
       (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)]));
       symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false);
@@ -2220,12 +2223,12 @@ yyreduce:
     break;
 
   case 87:
-#line 527 "parse-gram.y"
+#line 530 "parse-gram.y"
     { (yyval.chars) = (yyvsp[(1) - (1)].chars); }
     break;
 
   case 89:
-#line 534 "parse-gram.y"
+#line 537 "parse-gram.y"
     {
       muscle_code_grow ("epilogue", translate_code ((yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])), (yylsp[(2) - (2)]));
       gram_scanner_last_string_free ();
@@ -2234,7 +2237,7 @@ yyreduce:
 
 
 /* Line 1274 of yacc.c.  */
-#line 2238 "parse-gram.c"
+#line 2241 "parse-gram.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2454,7 +2457,7 @@ yyreturn:
 }
 
 
-#line 540 "parse-gram.y"
+#line 543 "parse-gram.y"
 
 
 
index bf80f1e121ab2f8438261375c68048a4d7737293..7c5fb25fac03ea4a9be1d6bdb728091dad6170f8 100644 (file)
@@ -473,8 +473,11 @@ rhs:
 | rhs symbol
     { grammar_current_rule_symbol_append ($2, @2); }
 | rhs "{...}"
-    { grammar_current_rule_action_append (gram_last_string,
-                                         gram_last_braced_code_loc); }
+    {
+      if (current_rule && current_rule->action)
+       grammar_midrule_action ();
+      grammar_current_rule_action_append ($2, @2);
+    }
 | rhs "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
index 94a8eeb5afcc5c98b2b5247edb8ebd79998e3755..4e464a7a8002f82ee5aecd30966730be8a6525aa 100644 (file)
 
 /* The current calling start condition: SC_RULE_ACTION or
    SC_SYMBOL_ACTION. */
-# define YY_DECL const char *code_lex (int sc_context)
+# define YY_DECL const char *code_lex (int sc_context, symbol_list *rule)
 YY_DECL;
 
 #define YY_USER_ACTION  location_compute (loc, &loc->end, yytext, yyleng);
 
-static void handle_action_dollar (char *cp, location dollar_loc);
-static void handle_action_at (char *cp, location at_loc);
+static void handle_action_dollar (symbol_list *rule, char *cp,
+                                 location dollar_loc);
+static void handle_action_at (symbol_list *rule, char *cp, location at_loc);
 static location the_location;
 static location *loc = &the_location;
-
-/* The rule being processed. */
-symbol_list *current_rule;
 %}
  /* C and C++ comments in code. */
 %x SC_COMMENT SC_LINE_COMMENT
@@ -153,8 +151,8 @@ splice       (\\[ \f\t\v]*\n)*
 
 <SC_RULE_ACTION>
 {
-  "$"("<"{tag}">")?(-?[0-9]+|"$")   handle_action_dollar (yytext, *loc);
-  "@"(-?[0-9]+|"$")                handle_action_at (yytext, *loc);
+  "$"("<"{tag}">")?(-?[0-9]+|"$")   handle_action_dollar (rule, yytext, *loc);
+  "@"(-?[0-9]+|"$")                handle_action_at (rule, yytext, *loc);
 
   "$"  {
     warn_at (*loc, _("stray `$'"));
@@ -238,11 +236,11 @@ int max_left_semantic_context = 0;
 `------------------------------------------------------------------*/
 
 static void
-handle_action_dollar (char *text, location dollar_loc)
+handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
 {
   const char *type_name = NULL;
   char *cp = text + 1;
-  int rule_length = symbol_list_length (current_rule->next);
+  int rule_length = symbol_list_length (rule->next);
 
   /* Get the type name if explicit. */
   if (*cp == '<')
@@ -257,15 +255,15 @@ handle_action_dollar (char *text, location dollar_loc)
   if (*cp == '$')
     {
       if (!type_name)
-       type_name = symbol_list_n_type_name_get (current_rule, dollar_loc, 0);
+       type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0);
       if (!type_name && typed)
        complain_at (dollar_loc, _("$$ of `%s' has no declared type"),
-                    current_rule->sym->tag);
+                    rule->sym->tag);
       if (!type_name)
        type_name = "";
       obstack_fgrow1 (&obstack_for_string,
                      "]b4_lhs_value([%s])[", type_name);
-      current_rule->used = true;
+      rule->used = true;
     }
   else
     {
@@ -279,16 +277,16 @@ handle_action_dollar (char *text, location dollar_loc)
            max_left_semantic_context = 1-n;
          if (!type_name && n > 0)
            type_name =
-             symbol_list_n_type_name_get (current_rule, dollar_loc, n);
+             symbol_list_n_type_name_get (rule, dollar_loc, n);
          if (!type_name && typed)
            complain_at (dollar_loc, _("$%d of `%s' has no declared type"),
-                        n, current_rule->sym->tag);
+                        n, rule->sym->tag);
          if (!type_name)
            type_name = "";
          obstack_fgrow3 (&obstack_for_string,
                          "]b4_rhs_value(%d, %d, [%s])[",
                          rule_length, n, type_name);
-         symbol_list_n_used_set (current_rule, n, true);
+         symbol_list_n_used_set (rule, n, true);
        }
       else
        complain_at (dollar_loc, _("integer out of range: %s"), quote (text));
@@ -302,10 +300,10 @@ handle_action_dollar (char *text, location dollar_loc)
 `------------------------------------------------------*/
 
 static void
-handle_action_at (char *text, location at_loc)
+handle_action_at (symbol_list *rule, char *text, location at_loc)
 {
   char *cp = text + 1;
-  int rule_length = symbol_list_length (current_rule->next);
+  int rule_length = symbol_list_length (rule->next);
   locations_flag = true;
 
   if (*cp == '$')
@@ -337,7 +335,7 @@ handle_action_at (char *text, location at_loc)
    INITIAL), the processing is different.  */
 
 static const char *
-translate_action (int sc_context, const char *a, location l)
+translate_action (int sc_context, symbol_list *rule, const char *a, location l)
 {
   const char *res;
   static bool initialized = false;
@@ -352,29 +350,28 @@ translate_action (int sc_context, const char *a, location l)
 
   loc->start = loc->end = l.start;
   yy_switch_to_buffer (yy_scan_string (a));
-  res = code_lex (sc_context);
+  res = code_lex (sc_context, rule);
   yy_delete_buffer (YY_CURRENT_BUFFER);
 
   return res;
 }
 
 const char *
-translate_rule_action (symbol_list *r, const char *a, location l)
+translate_rule_action (symbol_list *rule, const char *a, location l)
 {
-  current_rule = r;
-  return translate_action (SC_RULE_ACTION, a, l);
+  return translate_action (SC_RULE_ACTION, rule, a, l);
 }
 
 const char *
 translate_symbol_action (const char *a, location l)
 {
-  return translate_action (SC_SYMBOL_ACTION, a, l);
+  return translate_action (SC_SYMBOL_ACTION, NULL, a, l);
 }
 
 const char *
 translate_code (const char *a, location l)
 {
-  return translate_action (INITIAL, a, l);
+  return translate_action (INITIAL, NULL, a, l);
 }
 
 /*-----------------------------------------------.
index 25796dbd429b586fe1d6ba0ffe0815b2a35d35a3..93b9288c80a8493acf97f643dac43ca7484a74e8 100644 (file)
@@ -243,8 +243,6 @@ splice       (\\[ \f\t\v]*\n)*
 
   /* Code in between braces.  */
   "{" {
-    if (current_rule && current_rule->action)
-      grammar_midrule_action ();
     STRING_GROW;
     braces_level = 0;
     code_start = loc->start;
index 04951591ee00bd2d24bcf38a2d3875d8b0c8c4f8..cc2117f136fa9f73130ef8528925dddf28385886 100644 (file)
@@ -1004,3 +1004,79 @@ AT_CLEANUP
 AT_CHECK_EXPECT2()
 AT_CHECK_EXPECT2([%glr-parser])
 AT_CHECK_EXPECT2([%skeleton "lalr1.cc"])
+
+
+
+## --------------------------------------------- ##
+## Braced code in declaration in rules section.  ##
+## --------------------------------------------- ##
+
+AT_SETUP([Braced code in declaration in rules section])
+
+# Bison once mistook braced code in a declaration in the rules section to be a
+# rule action.
+
+AT_DATA_GRAMMAR([input.y],
+[[%{
+#include <stdio.h>
+void yyerror (char const *msg);
+int yylex (void);
+%}
+
+%error-verbose
+
+%%
+
+start:
+  {
+    printf ("Bison would once convert this action to a midrule because of the"
+           " subsequent braced code.\n");
+  }
+  ;
+
+%destructor { fprintf (stderr, "DESTRUCTOR\n"); } 'a';
+%printer { fprintf (yyoutput, "PRINTER"); } 'a';
+
+%%
+
+void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+int
+yylex (void)
+{
+  return 'a';
+}
+
+int
+main (void)
+{
+  yydebug = 1;
+  return !yyparse ();
+}
+]])
+
+AT_CHECK([bison -t -o input.c input.y])
+AT_COMPILE([input])
+AT_PARSER_CHECK([./input], 0,
+[[Bison would once convert this action to a midrule because of the subsequent braced code.
+]],
+[[Starting parse
+Entering state 0
+Reducing stack by rule 1 (line 22):
+-> $$ = nterm start ()
+Stack now 0
+Entering state 1
+Reading a token: Next token is token 'a' (PRINTER)
+syntax error, unexpected 'a', expecting $end
+Error: popping nterm start ()
+Stack now 0
+Cleanup: discarding lookahead token 'a' (PRINTER)
+DESTRUCTOR
+Stack now 0
+]])
+
+AT_CLEANUP