From: Joel E. Denny Date: Sat, 24 Jun 2006 06:51:27 +0000 (+0000) Subject: Fix bug that mistakes braced code in a declaration in the rules section X-Git-Tag: v2.3b~356 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/4210cd0bfcf94b41ce12725f19a314db5ad3ae65 Fix bug that mistakes braced code in a declaration in the rules section to be a rule action. Mentioned at . * 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. --- diff --git a/ChangeLog b/ChangeLog index 540f35df..41c6c6ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2006-06-24 Joel E. Denny + + Fix bug that mistakes braced code in a declaration in the rules section + to be a rule action. Mentioned at + . + * 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 Rename %before-definitions to %start-header and %after-definitions to diff --git a/src/parse-gram.c b/src/parse-gram.c index 0b1738d5..905ae160 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -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" diff --git a/src/parse-gram.y b/src/parse-gram.y index bf80f1e1..7c5fb25f 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -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 diff --git a/src/scan-code.l b/src/scan-code.l index 94a8eeb5..4e464a7a 100644 --- a/src/scan-code.l +++ b/src/scan-code.l @@ -45,18 +45,16 @@ /* 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)* { - "$"("<"{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); } /*-----------------------------------------------. diff --git a/src/scan-gram.l b/src/scan-gram.l index 25796dbd..93b9288c 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -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; diff --git a/tests/regression.at b/tests/regression.at index 04951591..cc2117f1 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -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 +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