[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]