diff options
Diffstat (limited to 'ext/ripper/lib/ripper/lexer.rb')
-rw-r--r-- | ext/ripper/lib/ripper/lexer.rb | 91 |
1 files changed, 71 insertions, 20 deletions
diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb index f6051c6341..a0f1cbeaa8 100644 --- a/ext/ripper/lib/ripper/lexer.rb +++ b/ext/ripper/lib/ripper/lexer.rb @@ -53,10 +53,27 @@ class Ripper end class Lexer < ::Ripper #:nodoc: internal use only - State = Struct.new(:to_int, :to_s) do + class State + attr_reader :to_int, :to_s + + def initialize(i) + @to_int = i + @to_s = Ripper.lex_state_name(i) + freeze + end + + def [](index) + case index + when 0, :to_int + @to_int + when 1, :to_s + @event + else + nil + end + end + alias to_i to_int - def initialize(i) super(i, Ripper.lex_state_name(i)).freeze end - # def inspect; "#<#{self.class}: #{self}>" end alias inspect to_s def pretty_print(q) q.text(to_s) end def ==(i) super or to_int == i end @@ -67,15 +84,40 @@ class Ripper def nobits?(i) to_int.nobits?(i) end end - Elem = Struct.new(:pos, :event, :tok, :state, :message) do + class Elem + attr_accessor :pos, :event, :tok, :state, :message + def initialize(pos, event, tok, state, message = nil) - super(pos, event, tok, State.new(state), message) + @pos = pos + @event = event + @tok = tok + @state = State.new(state) + @message = message + end + + def [](index) + case index + when 0, :pos + @pos + when 1, :event + @event + when 2, :tok + @tok + when 3, :state + @state + when 4, :message + @message + else + nil + end end def inspect "#<#{self.class}: #{event}@#{pos[0]}:#{pos[1]}:#{state}: #{tok.inspect}#{": " if message}#{message}>" end + alias to_s inspect + def pretty_print(q) q.group(2, "#<#{self.class}:", ">") { q.breakable @@ -94,9 +136,11 @@ class Ripper end def to_a - a = super - a.pop unless a.last - a + if @message + [@pos, @event, @tok, @state, @message] + else + [@pos, @event, @tok, @state] + end end end @@ -152,17 +196,19 @@ class Ripper def on_heredoc_dedent(v, w) ignored_sp = [] heredoc = @buf.last - heredoc.each_with_index do |e, i| - if Elem === e and e.event == :on_tstring_content and e.pos[1].zero? - tok = e.tok.dup if w > 0 and /\A\s/ =~ e.tok - if (n = dedent_string(e.tok, w)) > 0 - if e.tok.empty? - e.tok = tok[0, n] - e.event = :on_ignored_sp - next + if Array === heredoc + heredoc.each_with_index do |e, i| + if Elem === e and e.event == :on_tstring_content and e.pos[1].zero? + tok = e.tok.dup if w > 0 and /\A\s/ =~ e.tok + if (n = dedent_string(e.tok, w)) > 0 + if e.tok.empty? + e.tok = tok[0, n] + e.event = :on_ignored_sp + next + end + ignored_sp << [i, Elem.new(e.pos.dup, :on_ignored_sp, tok[0, n], e.state)] + e.pos[1] += n end - ignored_sp << [i, Elem.new(e.pos.dup, :on_ignored_sp, tok[0, n], e.state)] - e.pos[1] += n end end end @@ -182,7 +228,7 @@ class Ripper def on_heredoc_end(tok) @buf.push Elem.new([lineno(), column()], __callee__, tok, state()) - @buf = @stack.pop + @buf = @stack.pop unless @stack.empty? end def _push_token(tok) @@ -196,7 +242,12 @@ class Ripper end def on_error2(mesg, elem) - @errors.push Elem.new(elem.pos, __callee__, elem.tok, elem.state, mesg) + if elem + elem = Elem.new(elem.pos, __callee__, elem.tok, elem.state, mesg) + else + elem = Elem.new([lineno(), column()], __callee__, token(), state(), mesg) + end + @errors.push elem end PARSER_EVENTS.grep(/_error\z/) do |e| arity = PARSER_EVENT_TABLE.fetch(e) |