ruby-changes:36063
From: nobu <ko1@a...>
Date: Sun, 26 Oct 2014 12:24:27 +0900 (JST)
Subject: [ruby-changes:36063] nobu:r48144 (trunk): parse.y: Ripper.sexp returns error
nobu 2014-10-26 12:24:18 +0900 (Sun, 26 Oct 2014) New Revision: 48144 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48144 Log: parse.y: Ripper.sexp returns error * ext/ripper/lib/ripper/sexp.rb (Ripper.sexp, Ripper.sexp_raw): return nil on error. [ruby-dev:48678] [Bug #10405] Added files: trunk/test/ripper/test_sexp.rb Modified files: trunk/ChangeLog trunk/ext/ripper/lib/ripper/sexp.rb trunk/parse.y Index: ChangeLog =================================================================== --- ChangeLog (revision 48143) +++ ChangeLog (revision 48144) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Oct 26 12:24:15 2014 Nobuyoshi Nakada <nobu@r...> + + * ext/ripper/lib/ripper/sexp.rb (Ripper.sexp, Ripper.sexp_raw): + return nil on error. [ruby-dev:48678] [Bug #10405] + Sun Oct 25 11:24:24 2014 Martin Duerst <duerst@i...> * string.c: improved comment. Index: parse.y =================================================================== --- parse.y (revision 48143) +++ parse.y (revision 48144) @@ -278,6 +278,7 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L278 VALUE result; VALUE parsing_thread; int toplevel_p; + int error_p; #endif }; @@ -549,6 +550,8 @@ static VALUE ripper_dispatch3(struct par https://github.com/ruby/ruby/blob/trunk/parse.y#L550 static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE); static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE); static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE); +static void ripper_error_gen(struct parser_params *parser); +#define ripper_error() ripper_error_gen(parser) #define dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n)) #define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a)) @@ -1086,6 +1089,7 @@ stmt : keyword_alias fitem {lex_state = https://github.com/ruby/ruby/blob/trunk/parse.y#L1089 /*% $$ = dispatch2(var_alias, $2, $3); $$ = dispatch1(alias_error, $$); + ripper_error(); %*/ } | keyword_undef undef_list @@ -1231,6 +1235,7 @@ stmt : keyword_alias fitem {lex_state = https://github.com/ruby/ruby/blob/trunk/parse.y#L1235 /*% $$ = dispatch2(assign, dispatch1(var_field, $1), $3); $$ = dispatch1(assign_error, $$); + ripper_error(); %*/ } | lhs '=' mrhs @@ -1684,6 +1689,7 @@ mlhs_node : user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1689 $$ = dispatch2(const_path_field, $1, $3); if (in_def || in_single) { $$ = dispatch1(assign_error, $$); + ripper_error(); } %*/ } @@ -1697,6 +1703,7 @@ mlhs_node : user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1703 $$ = dispatch1(top_const_field, $2); if (in_def || in_single) { $$ = dispatch1(assign_error, $$); + ripper_error(); } %*/ } @@ -1708,6 +1715,7 @@ mlhs_node : user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1715 /*% $$ = dispatch1(var_field, $1); $$ = dispatch1(assign_error, $$); + ripper_error(); %*/ } ; @@ -1772,6 +1780,7 @@ lhs : user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1780 $$ = dispatch2(const_path_field, $1, $3); if (in_def || in_single) { $$ = dispatch1(assign_error, $$); + ripper_error(); } %*/ } @@ -1785,6 +1794,7 @@ lhs : user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1794 $$ = dispatch1(top_const_field, $2); if (in_def || in_single) { $$ = dispatch1(assign_error, $$); + ripper_error(); } %*/ } @@ -1795,6 +1805,7 @@ lhs : user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1805 $$ = NEW_BEGIN(0); /*% $$ = dispatch1(assign_error, $1); + ripper_error(); %*/ } ; @@ -1805,6 +1816,7 @@ cname : tIDENTIFIER https://github.com/ruby/ruby/blob/trunk/parse.y#L1816 yyerror("class/module name must be CONSTANT"); /*% $$ = dispatch1(class_name_error, $1); + ripper_error(); %*/ } | tCONSTANT @@ -2038,6 +2050,7 @@ arg : lhs '=' arg https://github.com/ruby/ruby/blob/trunk/parse.y#L2050 $$ = dispatch1(var_field, $1); $$ = dispatch3(opassign, $$, $2, $3); $$ = dispatch1(assign_error, $$); + ripper_error(); %*/ } | arg tDOT2 arg @@ -4536,6 +4549,7 @@ f_bad_arg : tCONSTANT https://github.com/ruby/ruby/blob/trunk/parse.y#L4549 $$ = 0; /*% $$ = dispatch1(param_error, $1); + ripper_error(); %*/ } | tIVAR @@ -4545,6 +4559,7 @@ f_bad_arg : tCONSTANT https://github.com/ruby/ruby/blob/trunk/parse.y#L4559 $$ = 0; /*% $$ = dispatch1(param_error, $1); + ripper_error(); %*/ } | tGVAR @@ -4554,6 +4569,7 @@ f_bad_arg : tCONSTANT https://github.com/ruby/ruby/blob/trunk/parse.y#L4569 $$ = 0; /*% $$ = dispatch1(param_error, $1); + ripper_error(); %*/ } | tCVAR @@ -4563,6 +4579,7 @@ f_bad_arg : tCONSTANT https://github.com/ruby/ruby/blob/trunk/parse.y#L4579 $$ = 0; /*% $$ = dispatch1(param_error, $1); + ripper_error(); %*/ } ; @@ -5315,6 +5332,7 @@ parser_yyerror(struct parser_params *par https://github.com/ruby/ruby/blob/trunk/parse.y#L5332 } #else dispatch1(parse_error, STR_NEW2(msg)); + ripper_error(); #endif /* !RIPPER */ return 0; } @@ -8759,7 +8777,7 @@ assignable_gen(struct parser_params *par https://github.com/ruby/ruby/blob/trunk/parse.y#L8777 #ifdef RIPPER ID id = get_id(lhs); # define assignable_result(x) get_value(lhs) -# define parser_yyerror(parser, x) dispatch1(assign_error, lhs) +# define parser_yyerror(parser, x) (dispatch1(assign_error, lhs), ripper_error()) #else # define assignable_result(x) (x) #endif @@ -10247,6 +10265,7 @@ parser_initialize(struct parser_params * https://github.com/ruby/ruby/blob/trunk/parse.y#L10265 parser->result = Qnil; parser->parsing_thread = Qnil; parser->toplevel_p = TRUE; + parser->error_p = FALSE; #endif #ifdef YYMALLOC parser->heap = NULL; @@ -10369,6 +10388,21 @@ static VALUE ripper_parser_end_seen_p(VA https://github.com/ruby/ruby/blob/trunk/parse.y#L10388 static VALUE ripper_parser_encoding(VALUE vparser); static VALUE ripper_parser_get_yydebug(VALUE self); static VALUE ripper_parser_set_yydebug(VALUE self, VALUE flag); + +/* + * call-seq: + * ripper#error? -> Boolean + * + * Return true if parsed source has errors. + */ +static VALUE +ripper_error_p(VALUE vparser) +{ + struct parser_params *parser; + + TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser); + return parser->error_p ? Qtrue : Qfalse; +} #endif /* @@ -10722,6 +10756,12 @@ ripper_get_value(VALUE v) https://github.com/ruby/ruby/blob/trunk/parse.y#L10756 } static void +ripper_error_gen(struct parser_params *parser) +{ + parser->error_p = TRUE; +} + +static void ripper_compile_error(struct parser_params *parser, const char *fmt, ...) { VALUE str; @@ -10731,6 +10771,7 @@ ripper_compile_error(struct parser_param https://github.com/ruby/ruby/blob/trunk/parse.y#L10771 str = rb_vsprintf(fmt, args); va_end(args); rb_funcall(parser->value, rb_intern("compile_error"), 1, str); + ripper_error_gen(parser); } static void @@ -11011,6 +11052,7 @@ InitVM_ripper(void) https://github.com/ruby/ruby/blob/trunk/parse.y#L11052 rb_define_method(Ripper, "encoding", rb_parser_encoding, 0); rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0); rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1); + rb_define_method(Ripper, "error?", ripper_error_p, 0); #ifdef RIPPER_DEBUG rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2); rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1); Index: ext/ripper/lib/ripper/sexp.rb =================================================================== --- ext/ripper/lib/ripper/sexp.rb (revision 48143) +++ ext/ripper/lib/ripper/sexp.rb (revision 48144) @@ -28,7 +28,9 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/sexp.rb#L28 # [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]] # def Ripper.sexp(src, filename = '-', lineno = 1) - SexpBuilderPP.new(src, filename, lineno).parse + builder = SexpBuilderPP.new(src, filename, lineno) + sexp = builder.parse + sexp unless builder.error? end # [EXPERIMENTAL] @@ -52,7 +54,9 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/sexp.rb#L54 # nil]]]] # def Ripper.sexp_raw(src, filename = '-', lineno = 1) - SexpBuilder.new(src, filename, lineno).parse + builder = SexpBuilder.new(src, filename, lineno) + sexp = builder.parse + sexp unless builder.error? end class SexpBuilderPP < ::Ripper #:nodoc: Index: test/ripper/test_sexp.rb =================================================================== --- test/ripper/test_sexp.rb (revision 0) +++ test/ripper/test_sexp.rb (revision 48144) @@ -0,0 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/test/ripper/test_sexp.rb#L1 +begin + require 'ripper' + require 'test/unit' + ripper_test = true + module TestRipper; end +rescue LoadError +end + +class TestRipper::Sexp < Test::Unit::TestCase + def test_compile_error + assert_nil Ripper.sexp("/") + assert_nil Ripper.sexp("-") + assert_nil Ripper.sexp("+") + assert_nil Ripper.sexp("*") + assert_nil Ripper.sexp("end") + assert_nil Ripper.sexp("end 1") + end +end if ripper_test Property changes on: test/ripper/test_sexp.rb ___________________________________________________________________ Added: svn:eol-style + LF -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/