Skip to content

Commit 098127d

Browse files
committed
parse.y: regexp error in ripper
* parse.y (ripper_flush_string_content, parser_parse_string): preserve parsed string content. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48504 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 3cdbc18 commit 098127d

File tree

3 files changed

+68
-9
lines changed

3 files changed

+68
-9
lines changed

ChangeLog

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
Thu Nov 20 02:09:34 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
1+
Thu Nov 20 02:10:31 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
2+
3+
* parse.y (ripper_flush_string_content, parser_parse_string):
4+
preserve parsed string content.
25

36
* parse.y (ripper_new_yylval): abstract function to create ripper
47
wrapper, and make it able to hold another object.

parse.y

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,8 @@ static VALUE new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VAL
503503

504504
#define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs))
505505

506+
RUBY_FUNC_EXPORTED VALUE rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALUE *errmsg);
507+
506508
static ID formal_argument_gen(struct parser_params*, ID);
507509
#define formal_argument(id) formal_argument_gen(parser, (id))
508510
static ID shadowing_lvar_gen(struct parser_params*,ID);
@@ -3991,6 +3993,19 @@ regexp : tREGEXP_BEG regexp_contents tREGEXP_END
39913993
}
39923994
$$ = node;
39933995
/*%
3996+
VALUE re = $2, opt = $3, src = 0, err;
3997+
int options = 0;
3998+
if (ripper_is_node_yylval(re)) {
3999+
$2 = RNODE(re)->nd_rval;
4000+
src = RNODE(re)->nd_cval;
4001+
}
4002+
if (ripper_is_node_yylval(opt)) {
4003+
$3 = RNODE(opt)->nd_rval;
4004+
options = (int)RNODE(opt)->nd_state;
4005+
}
4006+
if (src && NIL_P(rb_parser_reg_compile(parser, src, options, &err))) {
4007+
compile_error(PARSER_ARG "%"PRIsVALUE, err);
4008+
}
39944009
$$ = dispatch2(regexp_literal, $2, $3);
39954010
%*/
39964011
}
@@ -4215,7 +4230,7 @@ regexp_contents: /* none */
42154230
/*%%%*/
42164231
$$ = 0;
42174232
/*%
4218-
$$ = dispatch0(regexp_new);
4233+
$$ = ripper_new_yylval(0, dispatch0(regexp_new), 0);
42194234
%*/
42204235
}
42214236
| regexp_contents string_content
@@ -4242,7 +4257,20 @@ regexp_contents: /* none */
42424257
$$ = list_append(head, tail);
42434258
}
42444259
/*%
4245-
$$ = dispatch2(regexp_add, $1, $2);
4260+
VALUE s1 = 0, s2 = 0, n1 = $1, n2 = $2;
4261+
if (ripper_is_node_yylval(n1)) {
4262+
s1 = RNODE(n2)->nd_cval;
4263+
n1 = RNODE(n1)->nd_rval;
4264+
}
4265+
if (ripper_is_node_yylval(n2)) {
4266+
s2 = RNODE(n2)->nd_cval;
4267+
n2 = RNODE(n2)->nd_rval;
4268+
}
4269+
$$ = dispatch2(regexp_add, n1, n2);
4270+
if (s1 || s2) {
4271+
VALUE s = !s1 ? s2 : !s2 ? s1 : rb_str_plus(s1, s2);
4272+
$$ = ripper_new_yylval(0, $$, s);
4273+
}
42464274
%*/
42474275
}
42484276
;
@@ -4256,11 +4284,10 @@ string_content : tSTRING_CONTENT
42564284
}
42574285
string_dvar
42584286
{
4259-
/*%%%*/
42604287
lex_strterm = $<node>2;
4288+
/*%%%*/
42614289
$$ = NEW_EVSTR($3);
42624290
/*%
4263-
lex_strterm = $<node>2;
42644291
$$ = dispatch1(string_dvar, $3);
42654292
%*/
42664293
}
@@ -5158,8 +5185,8 @@ ripper_yylval_id(ID x)
51585185
{
51595186
return ripper_new_yylval(x, ID2SYM(x), 0);
51605187
}
5161-
# define set_yylval_str(x) (void)(x)
5162-
# define set_yylval_num(x) (void)(x)
5188+
# define set_yylval_str(x) (yylval.val = (x))
5189+
# define set_yylval_num(x) (yylval.val = ripper_new_yylval((x), 0, 0))
51635190
# define set_yylval_id(x) (void)(x)
51645191
# define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x))
51655192
# define set_yylval_literal(x) (void)(x)
@@ -6273,6 +6300,7 @@ parser_tokadd_string(struct parser_params *parser,
62736300
static void
62746301
ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc)
62756302
{
6303+
VALUE content = yylval.val;
62766304
if (!NIL_P(parser->delayed)) {
62776305
ptrdiff_t len = lex_p - parser->tokp;
62786306
if (len > 0) {
@@ -6281,6 +6309,10 @@ ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc)
62816309
ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
62826310
parser->tokp = lex_p;
62836311
}
6312+
if (!ripper_is_node_yylval(content))
6313+
content = ripper_new_yylval(0, 0, content);
6314+
yylval.val = content;
6315+
ripper_dispatch_scan_event(parser, tSTRING_CONTENT);
62846316
}
62856317

62866318
#define flush_string_content(enc) ripper_flush_string_content(parser, (enc))
@@ -6367,6 +6399,9 @@ parser_parse_string(struct parser_params *parser, NODE *quote)
63676399
}
63686400
if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
63696401
set_yylval_num(regx_options());
6402+
#ifdef RIPPER
6403+
ripper_dispatch_scan_event(parser, tREGEXP_END);
6404+
#endif
63706405
return tREGEXP_END;
63716406
}
63726407
if (space) {
@@ -10223,15 +10258,21 @@ reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *m
1022310258
NEW_LIT(Qnil)))));
1022410259
}
1022510260

10261+
static VALUE
10262+
parser_reg_compile(struct parser_params* parser, VALUE str, int options)
10263+
{
10264+
reg_fragment_setenc(str, options);
10265+
return rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
10266+
}
10267+
1022610268
static VALUE
1022710269
reg_compile_gen(struct parser_params* parser, VALUE str, int options)
1022810270
{
1022910271
VALUE re;
1023010272
VALUE err;
1023110273

10232-
reg_fragment_setenc(str, options);
1023310274
err = rb_errinfo();
10234-
re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
10275+
re = parser_reg_compile(parser, str, options);
1023510276
if (NIL_P(re)) {
1023610277
VALUE m = rb_attr_get(rb_errinfo(), idMesg);
1023710278
rb_set_errinfo(err);
@@ -10246,6 +10287,18 @@ reg_compile_gen(struct parser_params* parser, VALUE str, int options)
1024610287
return re;
1024710288
}
1024810289

10290+
VALUE
10291+
rb_parser_reg_compile(struct parser_params* parser, VALUE str, int options, VALUE *errmsg)
10292+
{
10293+
VALUE err = rb_errinfo();
10294+
VALUE re = parser_reg_compile(parser, str, options);
10295+
if (NIL_P(re)) {
10296+
*errmsg = rb_attr_get(rb_errinfo(), idMesg);
10297+
rb_set_errinfo(err);
10298+
}
10299+
return re;
10300+
}
10301+
1024910302
NODE*
1025010303
rb_parser_append_print(VALUE vparser, NODE *node)
1025110304
{

test/ripper/test_sexp.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ def test_compile_error
1414
assert_nil Ripper.sexp("*")
1515
assert_nil Ripper.sexp("end")
1616
assert_nil Ripper.sexp("end 1")
17+
assert_nil Ripper.sexp("/*")
18+
assert_nil Ripper.sexp("/*/")
19+
assert_nil Ripper.sexp("/+/")
1720
end
1821
end if ripper_test

0 commit comments

Comments
 (0)