ruby-changes:36423
From: nobu <ko1@a...>
Date: Thu, 20 Nov 2014 02:10:42 +0900 (JST)
Subject: [ruby-changes:36423] nobu:r48504 (trunk): parse.y: regexp error in ripper
nobu 2014-11-20 02:10:35 +0900 (Thu, 20 Nov 2014) New Revision: 48504 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48504 Log: parse.y: regexp error in ripper * parse.y (ripper_flush_string_content, parser_parse_string): preserve parsed string content. Modified files: trunk/ChangeLog trunk/parse.y trunk/test/ripper/test_sexp.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 48503) +++ ChangeLog (revision 48504) @@ -1,4 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 -Thu Nov 20 02:09:34 2014 Nobuyoshi Nakada <nobu@r...> +Thu Nov 20 02:10:31 2014 Nobuyoshi Nakada <nobu@r...> + + * parse.y (ripper_flush_string_content, parser_parse_string): + preserve parsed string content. * parse.y (ripper_new_yylval): abstract function to create ripper wrapper, and make it able to hold another object. Index: parse.y =================================================================== --- parse.y (revision 48503) +++ parse.y (revision 48504) @@ -503,6 +503,8 @@ static VALUE new_attr_op_assign_gen(stru https://github.com/ruby/ruby/blob/trunk/parse.y#L503 #define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs)) +RUBY_FUNC_EXPORTED VALUE rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALUE *errmsg); + static ID formal_argument_gen(struct parser_params*, ID); #define formal_argument(id) formal_argument_gen(parser, (id)) static ID shadowing_lvar_gen(struct parser_params*,ID); @@ -3991,6 +3993,19 @@ regexp : tREGEXP_BEG regexp_contents tR https://github.com/ruby/ruby/blob/trunk/parse.y#L3993 } $$ = node; /*% + VALUE re = $2, opt = $3, src = 0, err; + int options = 0; + if (ripper_is_node_yylval(re)) { + $2 = RNODE(re)->nd_rval; + src = RNODE(re)->nd_cval; + } + if (ripper_is_node_yylval(opt)) { + $3 = RNODE(opt)->nd_rval; + options = (int)RNODE(opt)->nd_state; + } + if (src && NIL_P(rb_parser_reg_compile(parser, src, options, &err))) { + compile_error(PARSER_ARG "%"PRIsVALUE, err); + } $$ = dispatch2(regexp_literal, $2, $3); %*/ } @@ -4215,7 +4230,7 @@ regexp_contents: /* none */ https://github.com/ruby/ruby/blob/trunk/parse.y#L4230 /*%%%*/ $$ = 0; /*% - $$ = dispatch0(regexp_new); + $$ = ripper_new_yylval(0, dispatch0(regexp_new), 0); %*/ } | regexp_contents string_content @@ -4242,7 +4257,20 @@ regexp_contents: /* none */ https://github.com/ruby/ruby/blob/trunk/parse.y#L4257 $$ = list_append(head, tail); } /*% - $$ = dispatch2(regexp_add, $1, $2); + VALUE s1 = 0, s2 = 0, n1 = $1, n2 = $2; + if (ripper_is_node_yylval(n1)) { + s1 = RNODE(n2)->nd_cval; + n1 = RNODE(n1)->nd_rval; + } + if (ripper_is_node_yylval(n2)) { + s2 = RNODE(n2)->nd_cval; + n2 = RNODE(n2)->nd_rval; + } + $$ = dispatch2(regexp_add, n1, n2); + if (s1 || s2) { + VALUE s = !s1 ? s2 : !s2 ? s1 : rb_str_plus(s1, s2); + $$ = ripper_new_yylval(0, $$, s); + } %*/ } ; @@ -4256,11 +4284,10 @@ string_content : tSTRING_CONTENT https://github.com/ruby/ruby/blob/trunk/parse.y#L4284 } string_dvar { - /*%%%*/ lex_strterm = $<node>2; + /*%%%*/ $$ = NEW_EVSTR($3); /*% - lex_strterm = $<node>2; $$ = dispatch1(string_dvar, $3); %*/ } @@ -5158,8 +5185,8 @@ ripper_yylval_id(ID x) https://github.com/ruby/ruby/blob/trunk/parse.y#L5185 { return ripper_new_yylval(x, ID2SYM(x), 0); } -# define set_yylval_str(x) (void)(x) -# define set_yylval_num(x) (void)(x) +# define set_yylval_str(x) (yylval.val = (x)) +# define set_yylval_num(x) (yylval.val = ripper_new_yylval((x), 0, 0)) # define set_yylval_id(x) (void)(x) # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x)) # define set_yylval_literal(x) (void)(x) @@ -6273,6 +6300,7 @@ parser_tokadd_string(struct parser_param https://github.com/ruby/ruby/blob/trunk/parse.y#L6300 static void ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc) { + VALUE content = yylval.val; if (!NIL_P(parser->delayed)) { ptrdiff_t len = lex_p - parser->tokp; if (len > 0) { @@ -6281,6 +6309,10 @@ ripper_flush_string_content(struct parse https://github.com/ruby/ruby/blob/trunk/parse.y#L6309 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT); parser->tokp = lex_p; } + if (!ripper_is_node_yylval(content)) + content = ripper_new_yylval(0, 0, content); + yylval.val = content; + ripper_dispatch_scan_event(parser, tSTRING_CONTENT); } #define flush_string_content(enc) ripper_flush_string_content(parser, (enc)) @@ -6367,6 +6399,9 @@ parser_parse_string(struct parser_params https://github.com/ruby/ruby/blob/trunk/parse.y#L6399 } if (!(func & STR_FUNC_REGEXP)) return tSTRING_END; set_yylval_num(regx_options()); +#ifdef RIPPER + ripper_dispatch_scan_event(parser, tREGEXP_END); +#endif return tREGEXP_END; } if (space) { @@ -10224,14 +10259,20 @@ reg_named_capture_assign_gen(struct pars https://github.com/ruby/ruby/blob/trunk/parse.y#L10259 } static VALUE +parser_reg_compile(struct parser_params* parser, VALUE str, int options) +{ + reg_fragment_setenc(str, options); + return rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline); +} + +static VALUE reg_compile_gen(struct parser_params* parser, VALUE str, int options) { VALUE re; VALUE err; - reg_fragment_setenc(str, options); err = rb_errinfo(); - re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline); + re = parser_reg_compile(parser, str, options); if (NIL_P(re)) { VALUE m = rb_attr_get(rb_errinfo(), idMesg); rb_set_errinfo(err); @@ -10245,6 +10286,18 @@ reg_compile_gen(struct parser_params* pa https://github.com/ruby/ruby/blob/trunk/parse.y#L10286 } return re; } + +VALUE +rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALUE *errmsg) +{ + VALUE err = rb_errinfo(); + VALUE re = parser_reg_compile(parser, str, options); + if (NIL_P(re)) { + *errmsg = rb_attr_get(rb_errinfo(), idMesg); + rb_set_errinfo(err); + } + return re; +} NODE* rb_parser_append_print(VALUE vparser, NODE *node) Index: test/ripper/test_sexp.rb =================================================================== --- test/ripper/test_sexp.rb (revision 48503) +++ test/ripper/test_sexp.rb (revision 48504) @@ -14,5 +14,8 @@ class TestRipper::Sexp < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/test/ripper/test_sexp.rb#L14 assert_nil Ripper.sexp("*") assert_nil Ripper.sexp("end") assert_nil Ripper.sexp("end 1") + assert_nil Ripper.sexp("/*") + assert_nil Ripper.sexp("/*/") + assert_nil Ripper.sexp("/+/") end end if ripper_test -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/