mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48144 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3bf0628a70
commit
d1ec43ae7a
4 changed files with 72 additions and 3 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Sun Oct 26 12:24:15 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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@it.aoyama.ac.jp>
|
Sun Oct 25 11:24:24 2014 Martin Duerst <duerst@it.aoyama.ac.jp>
|
||||||
|
|
||||||
* string.c: improved comment.
|
* string.c: improved comment.
|
||||||
|
|
|
@ -28,7 +28,9 @@ class Ripper
|
||||||
# [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]]
|
# [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]]
|
||||||
#
|
#
|
||||||
def Ripper.sexp(src, filename = '-', lineno = 1)
|
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
|
end
|
||||||
|
|
||||||
# [EXPERIMENTAL]
|
# [EXPERIMENTAL]
|
||||||
|
@ -52,7 +54,9 @@ class Ripper
|
||||||
# nil]]]]
|
# nil]]]]
|
||||||
#
|
#
|
||||||
def Ripper.sexp_raw(src, filename = '-', lineno = 1)
|
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
|
end
|
||||||
|
|
||||||
class SexpBuilderPP < ::Ripper #:nodoc:
|
class SexpBuilderPP < ::Ripper #:nodoc:
|
||||||
|
|
44
parse.y
44
parse.y
|
@ -278,6 +278,7 @@ struct parser_params {
|
||||||
VALUE result;
|
VALUE result;
|
||||||
VALUE parsing_thread;
|
VALUE parsing_thread;
|
||||||
int toplevel_p;
|
int toplevel_p;
|
||||||
|
int error_p;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -549,6 +550,8 @@ static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
|
||||||
static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
|
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_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 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 dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
|
||||||
#define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
|
#define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
|
||||||
|
@ -1086,6 +1089,7 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch2(var_alias, $2, $3);
|
$$ = dispatch2(var_alias, $2, $3);
|
||||||
$$ = dispatch1(alias_error, $$);
|
$$ = dispatch1(alias_error, $$);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| keyword_undef undef_list
|
| keyword_undef undef_list
|
||||||
|
@ -1231,6 +1235,7 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch2(assign, dispatch1(var_field, $1), $3);
|
$$ = dispatch2(assign, dispatch1(var_field, $1), $3);
|
||||||
$$ = dispatch1(assign_error, $$);
|
$$ = dispatch1(assign_error, $$);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| lhs '=' mrhs
|
| lhs '=' mrhs
|
||||||
|
@ -1684,6 +1689,7 @@ mlhs_node : user_variable
|
||||||
$$ = dispatch2(const_path_field, $1, $3);
|
$$ = dispatch2(const_path_field, $1, $3);
|
||||||
if (in_def || in_single) {
|
if (in_def || in_single) {
|
||||||
$$ = dispatch1(assign_error, $$);
|
$$ = dispatch1(assign_error, $$);
|
||||||
|
ripper_error();
|
||||||
}
|
}
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
|
@ -1697,6 +1703,7 @@ mlhs_node : user_variable
|
||||||
$$ = dispatch1(top_const_field, $2);
|
$$ = dispatch1(top_const_field, $2);
|
||||||
if (in_def || in_single) {
|
if (in_def || in_single) {
|
||||||
$$ = dispatch1(assign_error, $$);
|
$$ = dispatch1(assign_error, $$);
|
||||||
|
ripper_error();
|
||||||
}
|
}
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
|
@ -1708,6 +1715,7 @@ mlhs_node : user_variable
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch1(var_field, $1);
|
$$ = dispatch1(var_field, $1);
|
||||||
$$ = dispatch1(assign_error, $$);
|
$$ = dispatch1(assign_error, $$);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -1772,6 +1780,7 @@ lhs : user_variable
|
||||||
$$ = dispatch2(const_path_field, $1, $3);
|
$$ = dispatch2(const_path_field, $1, $3);
|
||||||
if (in_def || in_single) {
|
if (in_def || in_single) {
|
||||||
$$ = dispatch1(assign_error, $$);
|
$$ = dispatch1(assign_error, $$);
|
||||||
|
ripper_error();
|
||||||
}
|
}
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
|
@ -1785,6 +1794,7 @@ lhs : user_variable
|
||||||
$$ = dispatch1(top_const_field, $2);
|
$$ = dispatch1(top_const_field, $2);
|
||||||
if (in_def || in_single) {
|
if (in_def || in_single) {
|
||||||
$$ = dispatch1(assign_error, $$);
|
$$ = dispatch1(assign_error, $$);
|
||||||
|
ripper_error();
|
||||||
}
|
}
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
|
@ -1795,6 +1805,7 @@ lhs : user_variable
|
||||||
$$ = NEW_BEGIN(0);
|
$$ = NEW_BEGIN(0);
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch1(assign_error, $1);
|
$$ = dispatch1(assign_error, $1);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -1805,6 +1816,7 @@ cname : tIDENTIFIER
|
||||||
yyerror("class/module name must be CONSTANT");
|
yyerror("class/module name must be CONSTANT");
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch1(class_name_error, $1);
|
$$ = dispatch1(class_name_error, $1);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| tCONSTANT
|
| tCONSTANT
|
||||||
|
@ -2038,6 +2050,7 @@ arg : lhs '=' arg
|
||||||
$$ = dispatch1(var_field, $1);
|
$$ = dispatch1(var_field, $1);
|
||||||
$$ = dispatch3(opassign, $$, $2, $3);
|
$$ = dispatch3(opassign, $$, $2, $3);
|
||||||
$$ = dispatch1(assign_error, $$);
|
$$ = dispatch1(assign_error, $$);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| arg tDOT2 arg
|
| arg tDOT2 arg
|
||||||
|
@ -4536,6 +4549,7 @@ f_bad_arg : tCONSTANT
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch1(param_error, $1);
|
$$ = dispatch1(param_error, $1);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| tIVAR
|
| tIVAR
|
||||||
|
@ -4545,6 +4559,7 @@ f_bad_arg : tCONSTANT
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch1(param_error, $1);
|
$$ = dispatch1(param_error, $1);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| tGVAR
|
| tGVAR
|
||||||
|
@ -4554,6 +4569,7 @@ f_bad_arg : tCONSTANT
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch1(param_error, $1);
|
$$ = dispatch1(param_error, $1);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| tCVAR
|
| tCVAR
|
||||||
|
@ -4563,6 +4579,7 @@ f_bad_arg : tCONSTANT
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch1(param_error, $1);
|
$$ = dispatch1(param_error, $1);
|
||||||
|
ripper_error();
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -5315,6 +5332,7 @@ parser_yyerror(struct parser_params *parser, const char *msg)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
dispatch1(parse_error, STR_NEW2(msg));
|
dispatch1(parse_error, STR_NEW2(msg));
|
||||||
|
ripper_error();
|
||||||
#endif /* !RIPPER */
|
#endif /* !RIPPER */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -8759,7 +8777,7 @@ assignable_gen(struct parser_params *parser, ID id, NODE *val)
|
||||||
#ifdef RIPPER
|
#ifdef RIPPER
|
||||||
ID id = get_id(lhs);
|
ID id = get_id(lhs);
|
||||||
# define assignable_result(x) get_value(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
|
#else
|
||||||
# define assignable_result(x) (x)
|
# define assignable_result(x) (x)
|
||||||
#endif
|
#endif
|
||||||
|
@ -10247,6 +10265,7 @@ parser_initialize(struct parser_params *parser)
|
||||||
parser->result = Qnil;
|
parser->result = Qnil;
|
||||||
parser->parsing_thread = Qnil;
|
parser->parsing_thread = Qnil;
|
||||||
parser->toplevel_p = TRUE;
|
parser->toplevel_p = TRUE;
|
||||||
|
parser->error_p = FALSE;
|
||||||
#endif
|
#endif
|
||||||
#ifdef YYMALLOC
|
#ifdef YYMALLOC
|
||||||
parser->heap = NULL;
|
parser->heap = NULL;
|
||||||
|
@ -10369,6 +10388,21 @@ static VALUE ripper_parser_end_seen_p(VALUE vparser);
|
||||||
static VALUE ripper_parser_encoding(VALUE vparser);
|
static VALUE ripper_parser_encoding(VALUE vparser);
|
||||||
static VALUE ripper_parser_get_yydebug(VALUE self);
|
static VALUE ripper_parser_get_yydebug(VALUE self);
|
||||||
static VALUE ripper_parser_set_yydebug(VALUE self, VALUE flag);
|
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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -10721,6 +10755,12 @@ ripper_get_value(VALUE v)
|
||||||
return nd->nd_rval;
|
return nd->nd_rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ripper_error_gen(struct parser_params *parser)
|
||||||
|
{
|
||||||
|
parser->error_p = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
|
ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -10731,6 +10771,7 @@ ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
|
||||||
str = rb_vsprintf(fmt, args);
|
str = rb_vsprintf(fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
|
rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
|
||||||
|
ripper_error_gen(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -11011,6 +11052,7 @@ InitVM_ripper(void)
|
||||||
rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
|
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_get_yydebug, 0);
|
||||||
rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
|
rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
|
||||||
|
rb_define_method(Ripper, "error?", ripper_error_p, 0);
|
||||||
#ifdef RIPPER_DEBUG
|
#ifdef RIPPER_DEBUG
|
||||||
rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
|
rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
|
||||||
rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
|
rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
|
||||||
|
|
18
test/ripper/test_sexp.rb
Normal file
18
test/ripper/test_sexp.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
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
|
Loading…
Reference in a new issue