diff --git a/parse.y b/parse.y index e5a0e39dde..24fa3d36ff 100644 --- a/parse.y +++ b/parse.y @@ -12699,6 +12699,28 @@ ripper_state(VALUE self) return INT2NUM(p->lex.state); } +/* + * call-seq: + * ripper.token -> String + * + * Return the current token string. + */ +static VALUE +ripper_token(VALUE self) +{ + struct parser_params *p; + long pos, len; + + TypedData_Get_Struct(self, struct parser_params, &parser_data_type, p); + if (!ripper_initialized_p(p)) { + rb_raise(rb_eArgError, "method called for uninitialized object"); + } + if (NIL_P(p->parsing_thread)) return Qnil; + pos = p->lex.ptok - p->lex.pbeg; + len = p->lex.pcur - p->lex.ptok; + return rb_str_subseq(p->lex.lastline, pos, len); +} + #ifdef RIPPER_DEBUG /* :nodoc: */ static VALUE @@ -12762,6 +12784,7 @@ InitVM_ripper(void) rb_define_method(Ripper, "filename", ripper_filename, 0); rb_define_method(Ripper, "lineno", ripper_lineno, 0); rb_define_method(Ripper, "state", ripper_state, 0); + rb_define_method(Ripper, "token", ripper_token, 0); rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0); rb_define_method(Ripper, "encoding", rb_parser_encoding, 0); rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0); diff --git a/test/ripper/test_scanner_events.rb b/test/ripper/test_scanner_events.rb index 5fab5649ee..b46fcb5a9d 100644 --- a/test/ripper/test_scanner_events.rb +++ b/test/ripper/test_scanner_events.rb @@ -24,8 +24,9 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase lexer = Ripper::Lexer.new(str) if error lexer.singleton_class.class_eval do - define_method(:compile_error, error) - define_method(:on_parse_error, error) + define_method(:on_parse_error) {|ev| + yield __callee__, ev, token() + } end end lexer.lex.select {|_1,type,_2| type == sym }.map {|_1,_2,tok| tok } @@ -937,8 +938,8 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase assert_equal ["?\\M-H"], scan('CHAR', '?\\M-H') err = nil - assert_equal ["?\\M"], scan('CHAR', '?\\M ') {|e| err = [__callee__, e]} - assert_equal([:on_parse_error, "Invalid escape character syntax"], err) + assert_equal ["?\\M"], scan('CHAR', '?\\M ') {|*e| err = e} + assert_equal([:on_parse_error, "Invalid escape character syntax", "?\\M "], err) end def test_label