summaryrefslogtreecommitdiff
path: root/ext/ripper/lib/ripper/lexer.rb
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ripper/lib/ripper/lexer.rb')
-rw-r--r--ext/ripper/lib/ripper/lexer.rb84
1 files changed, 65 insertions, 19 deletions
diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb
index f6051c6341..6a3c04af30 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)