class RDoc::Parser::RipperStateLex

def self.end?(token)

Returns +true+ if lex state will be +END+ after +token+.
def self.end?(token)
  (token[:state] & EXPR_END)
end

def self.parse(code)

Returns tokens parsed from +code+.
def self.parse(code)
  lex = self.new(code)
  tokens = []
  begin
    while tk = lex.get_squashed_tk
      tokens.push tk
    end
  rescue StopIteration
  end
  tokens
end

def get_embdoc_tk(tk)

def get_embdoc_tk(tk)
 = tk[:text]
:on_embdoc_end == (embdoc_tk = get_squashed_tk)[:kind] do
ng = string + embdoc_tk[:text]
 = string + embdoc_tk[:text]
new(tk.line_no, tk.char_no, :on_embdoc, string, embdoc_tk.state)

def get_heredoc_tk(heredoc_name, indent)

def get_heredoc_tk(heredoc_name, indent)
 = ''
tk = nil
k = nil
heredoc_end?(heredoc_name, indent, tk = @tokens.shift) do
t_tk = tk unless start_tk
prev_tk.nil? or "\n" == prev_tk[:text][-1]) and 0 != tk[:char_no]
ring = string + (' ' * tk[:char_no])
ng = string + tk[:text]
_tk = tk
tk = tk unless start_tk
k = tk unless prev_tk
nshift tk # closing heredoc
c_tk = Token.new(start_tk.line_no, start_tk.char_no, :on_heredoc, string, prev_tk.state)
nshift heredoc_tk

def get_op_tk(tk)

def get_op_tk(tk)
nable_operators = %w[! != !~ % & * ** + +@ - -@ / < << <= <=> == === =~ > >= >> [] []= ^ ` | ~]
efinable_operators.include?(tk[:text]) and tk[:state] == EXPR_ARG then
state] = Ripper::Lexer::State.new(EXPR_ARG)
kind] = :on_ident
tk[:text] =~ /^[-+]$/ then
head = get_squashed_tk
 tk_ahead[:kind]
 :on_int, :on_float, :on_rational, :on_imaginary then
[:text] += tk_ahead[:text]
[:kind] = tk_ahead[:kind]
[:state] = tk_ahead[:state]
 :on_heredoc_beg, :on_tstring, :on_dstring # frozen/non-frozen string literal
[:text] += tk_ahead[:text]
[:kind] = tk_ahead[:kind]
[:state] = tk_ahead[:state]

uf.unshift tk_ahead

def get_regexp_tk(tk)

def get_regexp_tk(tk)
 = tk[:text]
= nil
o
r_str_tk = get_squashed_tk
nner_str_tk.nil?
eak
f :on_regexp_end == inner_str_tk[:kind]
ring = string + inner_str_tk[:text]
ate = inner_str_tk[:state]
eak

ring = string + inner_str_tk[:text]
new(tk.line_no, tk.char_no, :on_regexp, string, state)

def get_squashed_tk

def get_squashed_tk
  if @buf.empty?
    tk = @tokens.shift
  else
    tk = @buf.shift
  end
  return nil if tk.nil?
  case tk[:kind]
  when :on_symbeg then
    tk = get_symbol_tk(tk)
  when :on_tstring_beg then
    tk = get_string_tk(tk)
  when :on_backtick then
    if (tk[:state] & (EXPR_FNAME | EXPR_ENDFN)) != 0
      tk[:kind] = :on_ident
      tk[:state] = Ripper::Lexer::State.new(EXPR_ARG)
    else
      tk = get_string_tk(tk)
    end
  when :on_regexp_beg then
    tk = get_regexp_tk(tk)
  when :on_embdoc_beg then
    tk = get_embdoc_tk(tk)
  when :on_heredoc_beg then
    @heredoc_queue << retrieve_heredoc_info(tk)
  when :on_nl, :on_ignored_nl, :on_comment, :on_heredoc_end then
    if !@heredoc_queue.empty?
      get_heredoc_tk(*@heredoc_queue.shift)
    elsif tk[:text].nil? # :on_ignored_nl sometimes gives nil
      tk[:text] = ''
    end
  when :on_words_beg then
    tk = get_words_tk(tk)
  when :on_qwords_beg then
    tk = get_words_tk(tk)
  when :on_symbols_beg then
    tk = get_words_tk(tk)
  when :on_qsymbols_beg then
    tk = get_words_tk(tk)
  when :on_op then
    if '&.' == tk[:text]
      tk[:kind] = :on_period
    else
      tk = get_op_tk(tk)
    end
  end
  tk
end

def get_string_tk(tk)

def get_string_tk(tk)
 = tk[:text]
= nil
 :on_tstring
o
r_str_tk = get_squashed_tk
nner_str_tk.nil?
eak
f :on_tstring_end == inner_str_tk[:kind]
ring = string + inner_str_tk[:text]
ate = inner_str_tk[:state]
eak
f :on_label_end == inner_str_tk[:kind]
ring = string + inner_str_tk[:text]
ate = inner_str_tk[:state]
nd = :on_symbol
eak

ring = string + inner_str_tk[:text]
 :on_embexpr_beg == inner_str_tk[:kind] then
kind = :on_dstring if :on_tstring == kind
d
new(tk.line_no, tk.char_no, kind, string, state)

def get_symbol_tk(tk)

def get_symbol_tk(tk)
bol = true
_tk = Token.new(tk.line_no, tk.char_no, :on_symbol)
" == tk[:text] or ':"' == tk[:text] or tk[:text].start_with?('%s')
= get_string_tk(tk)
ol_tk[:text] = tk1[:text]
ol_tk[:state] = tk1[:state]
 (tk1 = get_squashed_tk)[:kind]
 :on_ident
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = tk1[:state]
 :on_tstring_content
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = get_squashed_tk[:state] # skip :on_tstring_end
 :on_tstring_end
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = tk1[:state]
 :on_op
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = tk1[:state]
 :on_ivar
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = tk1[:state]
 :on_cvar
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = tk1[:state]
 :on_gvar
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = tk1[:state]
 :on_const
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = tk1[:state]
 :on_kw
mbol_tk[:text] = ":#{tk1[:text]}"
mbol_tk[:state] = tk1[:state]

_symbol = false
 = tk1
symbol
 symbol_tk

def get_words_tk(tk)

def get_words_tk(tk)
 = ''
token = tk[:text]
quote = tk[:text].rstrip[-1]
o = tk[:line_no]
o = tk[:char_no]
= tk[:state]
ote =
 start_quote
 ?( then ?)
 ?[ then ?]
 ?{ then ?}
 ?< then ?>
 start_quote
ken = nil
o
 get_squashed_tk
k.nil?
d_token = end_quote
eak
f :on_tstring_content == tk[:kind] then
ring += tk[:text]
f :on_words_sep == tk[:kind] or :on_tstring_end == tk[:kind] then
 end_quote == tk[:text].strip then
end_token = tk[:text]
break
se
string += tk[:text]
d

ring += tk[:text]
 "#{start_token}#{string}#{end_token}"
new(line_no, char_no, :on_dstring, text, state)

def heredoc_end?(name, indent, tk)

def heredoc_end?(name, indent, tk)
 = false
_heredoc_end == tk[:kind] then
ame = tk[:text].chomp
ame.lstrip! if indent
ame == tk_name
sult = true

def initialize(code)

New lexer for +code+.
def initialize(code)
  @buf = []
  @heredoc_queue = []
  @inner_lex = InnerStateLex.new(code)
  @tokens = @inner_lex.parse([])
end

def retrieve_heredoc_info(tk)

def retrieve_heredoc_info(tk)
 tk[:text].gsub(/\A<<[-~]?(['"`]?)(.+)\1\z/, '\2')
 = tk[:text] =~ /\A<<[-~]/
 indent]