diff --git a/ChangeLog b/ChangeLog index d8fc17a966..daf4dac952 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Mon Apr 9 15:16:01 2012 Nobuyoshi Nakada + + * parse.y (string_content, parser_yylex): count brace nesting to + dispatch embexpr_end. [ruby-core:43775][Bug #6211] + Mon Apr 9 13:06:58 2012 Marc-Andre Lafortune * hash.c (rb_hash_set_default_proc): Accept nil, patch by Run Paint diff --git a/ext/ripper/eventids2.c b/ext/ripper/eventids2.c index dfe6c08619..946978954a 100644 --- a/ext/ripper/eventids2.c +++ b/ext/ripper/eventids2.c @@ -236,6 +236,7 @@ static const struct token_assoc { {tSTRING_BEG, &ripper_id_tstring_beg}, {tSTRING_CONTENT, &ripper_id_tstring_content}, {tSTRING_DBEG, &ripper_id_embexpr_beg}, + {tSTRING_DEND, &ripper_id_embexpr_end}, {tSTRING_DVAR, &ripper_id_embvar}, {tSTRING_END, &ripper_id_tstring_end}, {tSYMBEG, &ripper_id_symbeg}, diff --git a/parse.y b/parse.y index 0393dc1421..eaee57e4ad 100644 --- a/parse.y +++ b/parse.y @@ -213,6 +213,7 @@ struct parser_params { int parser_lpar_beg; int parser_in_single; int parser_in_def; + int parser_brace_nest; int parser_compile_for_eval; VALUE parser_cur_mid; int parser_in_defined; @@ -287,6 +288,7 @@ static int parser_yyerror(struct parser_params*, const char*); #define class_nest (parser->parser_class_nest) #define paren_nest (parser->parser_paren_nest) #define lpar_beg (parser->parser_lpar_beg) +#define brace_nest (parser->parser_brace_nest) #define in_single (parser->parser_in_single) #define in_def (parser->parser_in_def) #define compile_for_eval (parser->parser_compile_for_eval) @@ -760,7 +762,7 @@ static void token_info_pop(struct parser_params*, const char *token); %token tAMPER /* & */ %token tLAMBDA /* -> */ %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG -%token tSTRING_DBEG tSTRING_DVAR tSTRING_END tLAMBEG +%token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG /* * precedence table @@ -4219,16 +4221,21 @@ string_content : tSTRING_CONTENT lex_strterm = 0; lex_state = EXPR_BEG; } - compstmt '}' + { + $$ = brace_nest; + brace_nest = 0; + } + compstmt tSTRING_DEND { cond_stack = $1; cmdarg_stack = $2; lex_strterm = $3; + brace_nest = $4; /*%%%*/ - if ($4) $4->flags &= ~NODE_FL_NEWLINE; - $$ = new_evstr($4); + if ($5) $5->flags &= ~NODE_FL_NEWLINE; + $$ = new_evstr($5); /*% - $$ = dispatch1(string_embexpr, $4); + $$ = dispatch1(string_embexpr, $5); %*/ } ; @@ -7517,6 +7524,9 @@ parser_yylex(struct parser_params *parser) lex_state = EXPR_ENDFN; else lex_state = EXPR_ENDARG; + if (c == '}') { + if (!brace_nest--) c = tSTRING_DEND; + } return c; case ':': @@ -7650,6 +7660,7 @@ parser_yylex(struct parser_params *parser) return c; case '{': + ++brace_nest; if (lpar_beg && lpar_beg == paren_nest) { lex_state = EXPR_BEG; lpar_beg = 0; @@ -10390,6 +10401,7 @@ parser_initialize(struct parser_params *parser) parser->parser_class_nest = 0; parser->parser_paren_nest = 0; parser->parser_lpar_beg = 0; + parser->parser_brace_nest = 0; parser->parser_in_single = 0; parser->parser_in_def = 0; parser->parser_in_defined = 0; diff --git a/test/ripper/test_scanner_events.rb b/test/ripper/test_scanner_events.rb index e792ca8f4d..5b58dd8289 100644 --- a/test/ripper/test_scanner_events.rb +++ b/test/ripper/test_scanner_events.rb @@ -210,8 +210,6 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase end def test_embexpr_end -=begin - # currently detected as "rbrace" assert_equal [], scan('embexpr_end', '') assert_equal ['}'], @@ -222,7 +220,6 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase scan('embexpr_end', '%Q[#{expr}]') assert_equal ['}'], scan('embexpr_end', "m(<