class Parser::Lexer

line 3 “lib/parser/lexer.rl”

BEFORE YOU START ===

Read the Ruby Hacking Guide chapter 11, available in English at whitequark.org/blog/2013/04/01/ruby-hacking-guide-ch-11-finite-state-lexer/

Remember two things about Ragel scanners:

1) Longest match wins.

2) If two matches have the same length, the first
   in source code wins.

General rules of making Ragel and Bison happy:

* `p` (position) and `@te` contain the index of the character
  they're pointing to ("current"), plus one. `@ts` contains the index
  of the corresponding character. The code for extracting matched token is:

     @source_buffer.slice(@ts...@te)

* If your input is `foooooooobar` and the rule is:

     'f' 'o'+

  the result will be:

     foooooooobar
     ^ ts=0   ^ p=te=9

* A Ragel lexer action should not emit more than one token, unless
  you know what you are doing.

* All Ragel commands (fnext, fgoto, ...) end with a semicolon.

* If an action emits the token and transitions to another state, use
  these Ragel commands:

     emit($whatever)
     fnext $next_state; fbreak;

  If you perform `fgoto` in an action which does not emit a token nor
  rewinds the stream pointer, the parser's side-effectful,
  context-sensitive lookahead actions will break in a hard to detect
  and debug way.

* If an action does not emit a token:

     fgoto $next_state;

* If an action features lookbehind, i.e. matches characters with the
  intent of passing them to another action:

     p = @ts - 1
     fgoto $next_state;

  or, if the lookbehind consists of a single character:

     fhold; fgoto $next_state;

* Ragel merges actions. So, if you have `e_lparen = '(' %act` and
  `c_lparen = '('` and a lexer action `e_lparen | c_lparen`, the result
  _will_ invoke the action `act`.

  e_something stands for "something with **e**mbedded action".

* EOF is explicit and is matched by `c_eof`. If you want to introspect
  the state of the lexer, add this rule to the state:

     c_eof => do_eof;

* If you proceed past EOF, the lexer will complain:

     NoMethodError: undefined method `ord' for nil:NilClass

Constants

ESCAPES

line 82 “lib/parser/lexer.rl” %

KEYWORDS
KEYWORDS_BEGIN
LEX_STATES
PUNCTUATION

Mapping of strings to parser tokens.

PUNCTUATION_BEGIN
RBRACE_OR_RBRACK
REGEXP_META_CHARACTERS

Attributes

_lex_eof_trans[RW]
_lex_from_state_actions[RW]
_lex_index_offsets[RW]
_lex_indicies[RW]
_lex_key_spans[RW]
_lex_to_state_actions[RW]
_lex_trans_actions[RW]
_lex_trans_keys[RW]
_lex_trans_targs[RW]
lex_en_expr_arg[RW]
lex_en_expr_beg[RW]
lex_en_expr_cmdarg[RW]
lex_en_expr_dot[RW]
lex_en_expr_end[RW]
lex_en_expr_endarg[RW]
lex_en_expr_endfn[RW]
lex_en_expr_fname[RW]
lex_en_expr_labelarg[RW]
lex_en_expr_mid[RW]
lex_en_expr_value[RW]
lex_en_expr_variable[RW]
lex_en_interp_backslash_delimited[RW]
lex_en_interp_string[RW]
lex_en_interp_words[RW]
lex_en_leading_dot[RW]
lex_en_line_begin[RW]
lex_en_line_comment[RW]
lex_en_plain_backslash_delimited[RW]
lex_en_plain_string[RW]
lex_en_plain_words[RW]
lex_en_regexp_modifiers[RW]
lex_error[RW]
lex_start[RW]
cmdarg[RW]
comments[RW]
cond[RW]
diagnostics[RW]
force_utf32[RW]
in_kwarg[RW]
source_buffer[R]
static_env[RW]
tokens[RW]

Public Class Methods

new(version) click to toggle source
# File lib/parser/lexer.rb, line 10610
def initialize(version)
  @version    = version
  @static_env = nil

  @tokens     = nil
  @comments   = nil

  reset
end

Public Instance Methods

advance() click to toggle source

Return next token: [type, value].

# File lib/parser/lexer.rb, line 10764
  def advance
    if @token_queue.any?
      return @token_queue.shift
    end

    # Ugly, but dependent on Ragel output. Consider refactoring it somehow.
    klass = self.class
    _lex_trans_keys         = klass.send :_lex_trans_keys
    _lex_key_spans          = klass.send :_lex_key_spans
    _lex_index_offsets      = klass.send :_lex_index_offsets
    _lex_indicies           = klass.send :_lex_indicies
    _lex_trans_targs        = klass.send :_lex_trans_targs
    _lex_trans_actions      = klass.send :_lex_trans_actions
    _lex_to_state_actions   = klass.send :_lex_to_state_actions
    _lex_from_state_actions = klass.send :_lex_from_state_actions
    _lex_eof_trans          = klass.send :_lex_eof_trans

    pe = @source_pts.size + 2
    p, eof = @p, pe

    @command_state = (@cs == klass.lex_en_expr_value ||
                      @cs == klass.lex_en_line_begin)

    
# line 10789 "lib/parser/lexer.rb"
begin
        testEof = false
        _slen, _trans, _keys, _inds, _acts, _nacts = nil
        _goto_level = 0
        _resume = 10
        _eof_trans = 15
        _again = 20
        _test_eof = 30
        _out = 40
        while true
        if _goto_level <= 0
        if p == pe
                _goto_level = _test_eof
                next
        end
        if  @cs == 0
                _goto_level = _out
                next
        end
        end
        if _goto_level <= _resume
        case _lex_from_state_actions[ @cs] 
        when 78 then
# line 1 "NONE"
                begin
 @ts = p
                end
# line 10817 "lib/parser/lexer.rb"
        end
        _keys =  @cs << 1
        _inds = _lex_index_offsets[ @cs]
        _slen = _lex_key_spans[ @cs]
        _trans = if (   _slen > 0 && 
                        _lex_trans_keys[_keys] <= ( (@source_pts[p] || 0)) && 
                        ( (@source_pts[p] || 0)) <= _lex_trans_keys[_keys + 1] 
                    ) then
                        _lex_indicies[ _inds + ( (@source_pts[p] || 0)) - _lex_trans_keys[_keys] ] 
                 else 
                        _lex_indicies[ _inds + _slen ]
                 end
        end
        if _goto_level <= _eof_trans
         @cs = _lex_trans_targs[_trans]
        if _lex_trans_actions[_trans] != 0
        case _lex_trans_actions[_trans]
        when 26 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
        when 97 then
# line 766 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
        when 27 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
        when 65 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
        when 68 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
        when 266 then
# line 1152 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 34 then
# line 1421 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 36 then
# line 1437 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 38 then
# line 1465 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 53 then
# line 1651 "lib/parser/lexer.rl"
                begin
 heredoc_e      = p             end
        when 306 then
# line 1705 "lib/parser/lexer.rl"
                begin
 @escape = nil          end
        when 335 then
# line 1778 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 411 then
# line 1996 "lib/parser/lexer.rl"
                begin
 @num_base = 16; @num_digits_s = p              end
        when 405 then
# line 1997 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = p              end
        when 408 then
# line 1998 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = p              end
        when 402 then
# line 1999 "lib/parser/lexer.rl"
                begin
 @num_base = 2;  @num_digits_s = p              end
        when 417 then
# line 2000 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
        when 385 then
# line 2001 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
        when 397 then
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 392 then
# line 2059 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 390 then
# line 2060 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 74 then
# line 2195 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 7 then
# line 1 "NONE"
                begin
 @te = p+1
                end
        when 94 then
# line 1007 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DBEG, '#{'.freeze)

    if current_literal.heredoc?
      current_literal.saved_herebody_s = @herebody_s
      @herebody_s = nil
    end

    current_literal.start_interp_brace
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 747
                _goto_level = _again
                next
        end

   end
                end
        when 5 then
# line 952 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DVAR, nil, @ts, @ts + 1)

    p = @ts
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end

   end
                end
        when 90 then
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 89 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 95 then
# line 952 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DVAR, nil, @ts, @ts + 1)

    p = @ts
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end

   end
                end
        when 92 then
# line 939 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    literal.extend_space @ts, @te
   end
                end
        when 93 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 6 then
# line 839 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 4 then
# line 815 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 121 then
# line 1007 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DBEG, '#{'.freeze)

    if current_literal.heredoc?
      current_literal.saved_herebody_s = @herebody_s
      @herebody_s = nil
    end

    current_literal.start_interp_brace
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 747
                _goto_level = _again
                next
        end

   end
                end
        when 10 then
# line 952 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DVAR, nil, @ts, @ts + 1)

    p = @ts
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end

   end
                end
        when 118 then
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 117 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 122 then
# line 952 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DVAR, nil, @ts, @ts + 1)

    p = @ts
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end

   end
                end
        when 120 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 11 then
# line 839 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 9 then
# line 815 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 144 then
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 143 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 146 then
# line 939 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    literal.extend_space @ts, @te
   end
                end
        when 147 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 150 then
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 149 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 152 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 159 then
# line 1007 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DBEG, '#{'.freeze)

    if current_literal.heredoc?
      current_literal.saved_herebody_s = @herebody_s
      @herebody_s = nil
    end

    current_literal.start_interp_brace
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 747
                _goto_level = _again
                next
        end

   end
                end
        when 13 then
# line 952 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DVAR, nil, @ts, @ts + 1)

    p = @ts
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end

   end
                end
        when 156 then
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 155 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 160 then
# line 952 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    current_literal.flush_string
    current_literal.extend_content

    emit(:tSTRING_DVAR, nil, @ts, @ts + 1)

    p = @ts
        begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end

   end
                end
        when 158 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 12 then
# line 815 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 162 then
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 161 then
# line 815 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    string = tok

    # tLABEL_END is only possible in non-cond context on >= 2.2
    if @version >= 22 && !@cond.active?
      lookahead = @source_buffer.slice(@te...@te+2)
    end

    current_literal = literal
    if !current_literal.heredoc? &&
          (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead))
      if token[0] == :tLABEL_END
        p += 1
        pop_literal
         @cs = 740;
      else
         @cs = (pop_literal);
      end
        begin
                p += 1
                _goto_level = _out
                next
        end

    else
      current_literal.extend_string(string, @ts, @te)
    end
   end
                end
        when 164 then
# line 1083 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tREGEXP_OPT, tok(@ts, @te - 1), @ts, @te - 1)
        p = p - 1;      begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 165 then
# line 1071 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        unknown_options = tok.scan(/[^imxouesn]/)
        if unknown_options.any?
          diagnostic :error, :regexp_options,
                     { :options => unknown_options.join }
        end

        emit(:tREGEXP_OPT)
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 14 then
# line 1211 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        if    tok =~ /^\$([1-9][0-9]*)$/
          emit(:tNTH_REF, tok(@ts + 1).to_i)
        elsif tok =~ /^\$([&`'+])$/
          emit(:tBACK_REF)
        else
          emit(:tGVAR)
        end

         @cs = (stack_pop);     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 166 then
# line 1211 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if    tok =~ /^\$([1-9][0-9]*)$/
          emit(:tNTH_REF, tok(@ts + 1).to_i)
        elsif tok =~ /^\$([&`'+])$/
          emit(:tBACK_REF)
        else
          emit(:tGVAR)
        end

         @cs = (stack_pop);     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 168 then
# line 1224 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if tok =~ /^@@[0-9]/
          diagnostic :error, :cvar_name, { :name => tok }
        end

        emit(:tCVAR)
         @cs = (stack_pop);     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 167 then
# line 1234 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if tok =~ /^@[0-9]/
          diagnostic :error, :ivar_name, { :name => tok }
        end

        emit(:tIVAR)
         @cs = (stack_pop);     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 189 then
# line 1255 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(KEYWORDS_BEGIN);
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 175 then
# line 1263 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tIDENTIFIER)
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 16 then
# line 1267 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1
            @cs = 755;  begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end
  end
                end
        when 172 then
# line 1276 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 184 then
# line 1280 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1; p = p - 1;   begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 18 then
# line 1286 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        if version?(23)
          type, delimiter = tok[0..-2], tok[-1].chr
                begin
                 @cs = (push_literal(type, delimiter, @ts))
                _goto_level = _again
                next
        end

        else
          p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

        end
       end
                end
        when 171 then
# line 1299 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 170 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 188 then
# line 1255 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(KEYWORDS_BEGIN);
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 185 then
# line 1259 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tCONSTANT)
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 187 then
# line 1263 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tIDENTIFIER)
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 182 then
# line 1267 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
            @cs = 755;  begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end
  end
                end
        when 178 then
# line 1276 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 183 then
# line 1283 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 176 then
# line 1296 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 181 then
# line 1299 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 17 then
# line 1276 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  emit_table(PUNCTUATION)
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 15 then
# line 1299 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 174 then
# line 1 "NONE"
                begin
        case  @act
        when 31 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS_BEGIN);
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 32 then
        begin begin p = (( @te))-1; end
 emit(:tCONSTANT)
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 33 then
        begin begin p = (( @te))-1; end
 emit(:tIDENTIFIER)
            @cs = 429;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
end 
                        end
        when 20 then
# line 1311 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1)
           p = p - 1;  @cs = 740;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 191 then
# line 1317 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 190 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 193 then
# line 1314 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 192 then
# line 1317 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 19 then
# line 1317 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 199 then
# line 1343 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 457;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 198 then
# line 1349 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 197 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 209 then
# line 1328 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tCONSTANT)
            @cs = (arg_or_cmdarg);      begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 200 then
# line 1332 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tIDENTIFIER)
            @cs = (arg_or_cmdarg);      begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 205 then
# line 1343 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 457;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 203 then
# line 1346 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 208 then
# line 1349 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 232 then
# line 1407 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        # Unlike expr_beg as invoked in the next rule, do not warn
        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 215 then
# line 1425 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        if tok(tm, tm + 1) == '/'.freeze
          # Ambiguous regexp literal.
          diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1)
        end

        p = tm - 1
                begin
                 @cs = 526
                _goto_level = _again
                next
        end

       end
                end
        when 221 then
# line 1449 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1; p = p - 1;   begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 22 then
# line 1457 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1;    begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 223 then
# line 1466 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = tm - 1;     begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 37 then
# line 1475 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 210 then
# line 1489 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 211 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 222 then
# line 1416 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 218 then
# line 1438 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) },
                   range(tm, @te)

        p = tm - 1
                begin
                 @cs = 526
                _goto_level = _again
                next
        end

       end
                end
        when 220 then
# line 1454 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 214 then
# line 1475 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 213 then
# line 1480 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 231 then
# line 1489 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 23 then
# line 1480 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
                end
        when 39 then
# line 1489 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 21 then
# line 1 "NONE"
                begin
        case  @act
        when 59 then
        begin begin p = (( @te))-1; end

        if tok(tm, tm + 1) == '/'.freeze
          # Ambiguous regexp literal.
          diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1)
        end

        p = tm - 1
                begin
                 @cs = 526
                _goto_level = _again
                next
        end

      end
        when 60 then
        begin begin p = (( @te))-1; end

        diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) },
                   range(tm, @te)

        p = tm - 1
                begin
                 @cs = 526
                _goto_level = _again
                next
        end

      end
        when 65 then
        begin begin p = (( @te))-1; end

        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

      end
        else
        begin begin p = (( @te))-1; end
end
end 
                        end
        when 41 then
# line 1525 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1
                begin
                 @cs = 457
                _goto_level = _again
                next
        end
  end
                end
        when 236 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 237 then
# line 1525 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 457
                _goto_level = _again
                next
        end
  end
                end
        when 42 then
# line 1525 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = @ts - 1
                begin
                 @cs = 457
                _goto_level = _again
                next
        end
  end
                end
        when 40 then
# line 1 "NONE"
                begin
        case  @act
        when 72 then
        begin begin p = (( @te))-1; end

        if @cond.active?
          emit(:kDO_COND, 'do'.freeze, @te - 2, @te)
        else
          emit(:kDO, 'do'.freeze, @te - 2, @te)
        end
         @cs = 747;     begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 73 then
        begin begin p = (( @te))-1; end
 p = @ts - 1
                begin
                 @cs = 457
                _goto_level = _again
                next
        end
 end
end 
                        end
        when 247 then
# line 1552 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_do(true)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 240 then
# line 1558 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 241 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 242 then
# line 1555 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 245 then
# line 1558 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 251 then
# line 1582 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 250 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 259 then
# line 1574 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1;  begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 253 then
# line 1576 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 257 then
# line 1582 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 252 then
# line 1 "NONE"
                begin
        case  @act
        when 80 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 81 then
        begin begin p = (( @te))-1; end
 p = @ts - 1;   begin
                 @cs = 526
                _goto_level = _again
                next
        end
 end
end 
                        end
        when 287 then
# line 1599 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = p - 1;
        if tok.start_with? '-'.freeze
          emit(:tUMINUS_NUM, '-'.freeze, @ts, @ts + 1)
           @cs = 755;   begin
                p += 1
                _goto_level = _out
                next
        end

        end
       end
                end
        when 288 then
# line 1619 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        type = delimiter = tok[0].chr
        p = p - 1;      begin
                 @cs = (push_literal(type, delimiter, @ts))
                _goto_level = _again
                next
        end

       end
                end
        when 282 then
# line 1626 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        type, delimiter = @source_buffer.slice(@ts).chr, tok[-1].chr
                begin
                 @cs = (push_literal(type, delimiter, @ts))
                _goto_level = _again
                next
        end

       end
                end
        when 49 then
# line 1633 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        type, delimiter = tok[0..-2], tok[-1].chr
                begin
                 @cs = (push_literal(type, delimiter, @ts))
                _goto_level = _again
                next
        end

       end
                end
        when 289 then
# line 1679 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        type, delimiter = tok, tok[-1].chr
                begin
                 @cs = (push_literal(type, delimiter, @ts))
                _goto_level = _again
                next
        end

       end
                end
        when 52 then
# line 1693 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tSYMBOL, tok(@ts + 1), @ts)
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 303 then
# line 1724 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        escape = { " "  => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t',
                   "\v" => '\v', "\f" => '\f' }[@source_buffer.slice(@ts + 1)]
        diagnostic :warning, :invalid_escape_use, { :escape => escape }, range

        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 302 then
# line 1734 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1)
       end
                end
        when 290 then
# line 1773 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION_BEGIN)
                begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 46 then
# line 1793 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = p - 1;

        if version?(18)
          ident = tok(@ts, @te - 2)

          emit((@source_buffer.slice(@ts) =~ /[A-Z]/) ? :tCONSTANT : :tIDENTIFIER,
               ident, @ts, @te - 2)
          p = p - 1; # continue as a symbol

          if !@static_env.nil? && @static_env.declared?(ident)
             @cs = 755;
          else
             @cs = (arg_or_cmdarg);
          end
        else
          emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1)
           @cs = 740;
        end

                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 276 then
# line 1839 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1
                begin
                 @cs = 161
                _goto_level = _again
                next
        end
  end
                end
        when 50 then
# line 1852 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1;    begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 262 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 286 then
# line 1609 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tSTAR, '*'.freeze)
                begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 283 then
# line 1633 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        type, delimiter = tok[0..-2], tok[-1].chr
                begin
                 @cs = (push_literal(type, delimiter, @ts))
                _goto_level = _again
                next
        end

       end
                end
        when 281 then
# line 1639 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1)
       end
                end
        when 291 then
# line 1693 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1), @ts)
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 301 then
# line 1734 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1)
       end
                end
        when 307 then
# line 1740 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 284 then
# line 1773 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION_BEGIN)
                begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 329 then
# line 1196 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    emit(:tIDENTIFIER)

    if !@static_env.nil? && @static_env.declared?(tok)
       @cs = 429;       begin
                p += 1
                _goto_level = _out
                next
        end

    else
       @cs = (arg_or_cmdarg);   begin
                p += 1
                _goto_level = _out
                next
        end

    end
   end
                end
        when 273 then
# line 1836 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 275 then
# line 1839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 161
                _goto_level = _again
                next
        end
  end
                end
        when 278 then
# line 1852 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1;  begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 48 then
# line 1639 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1)
       end
                end
        when 55 then
# line 1707 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 47 then
# line 1836 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
                end
        when 51 then
# line 1852 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = @ts - 1;    begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 45 then
# line 1 "NONE"
                begin
        case  @act
        when 103 then
        begin begin p = (( @te))-1; end
 emit_table(PUNCTUATION_BEGIN)
                begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 104 then
        begin begin p = (( @te))-1; end
 emit(:kRESCUE, 'rescue'.freeze, @ts, tm)
           p = tm - 1
            @cs = 502;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 105 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS_BEGIN)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 107 then
        begin begin p = (( @te))-1; end
 p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
 end
        when 108 then
        begin begin p = (( @te))-1; end

    emit(:tIDENTIFIER)

    if !@static_env.nil? && @static_env.declared?(tok)
       @cs = 429;       begin
                p += 1
                _goto_level = _out
                next
        end

    else
       @cs = (arg_or_cmdarg);   begin
                p += 1
                _goto_level = _out
                next
        end

    end
  end
        when 111 then
        begin begin p = (( @te))-1; end
 p = @ts - 1;   begin
                 @cs = 755
                _goto_level = _again
                next
        end
 end
end 
                        end
        when 337 then
# line 1872 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 338 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 339 then
# line 1860 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 343 then
# line 1872 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 58 then
# line 1882 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 347 then
# line 1887 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
                begin
                 @cs = (push_literal(tok, tok, @ts))
                _goto_level = _again
                next
        end

       end
                end
        when 346 then
# line 1897 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 345 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 349 then
# line 1891 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 348 then
# line 1897 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 57 then
# line 1897 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 526
                _goto_level = _again
                next
        end
  end
                end
        when 379 then
# line 1908 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tLAMBDA, '->'.freeze, @ts, @ts + 2)

        @lambda_stack.push @paren_nest
         @cs = 429;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 72 then
# line 1945 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:kCLASS, 'class'.freeze, @ts, @ts + 5)
           emit(:tLSHFT, '<<'.freeze,    @te - 2, @te)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 357 then
# line 2080 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        type, delimiter = tok, tok[-1].chr
                begin
                 @cs = (push_literal(type, delimiter, @ts, nil, false, false, true))
                _goto_level = _again
                next
        end

       end
                end
        when 60 then
# line 2098 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1;    begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end
  end
                end
        when 376 then
# line 2105 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 436;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 370 then
# line 2132 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 363 then
# line 2136 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit_table(PUNCTUATION)
        @cond.lexpop; @cmdarg.lexpop

        if RBRACE_OR_RBRACK.include?(tok)
           @cs = 494;
        else # )
          # fnext expr_endfn; ?
        end

                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 375 then
# line 2150 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tOP_ASGN, tok(@ts, @te - 1))
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 361 then
# line 2154 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tEH, '?'.freeze)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 358 then
# line 2162 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 360 then
# line 2175 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tSEMI, ';'.freeze)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 425 then
# line 2178 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        diagnostic :error, :bare_backslash, nil, range(@ts, @ts + 1)
        p = p - 1;
       end
                end
        when 356 then
# line 2184 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] }
       end
                end
        when 355 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 435 then
# line 1941 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(KEYWORDS)
            @cs = 316;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 433 then
# line 1945 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:kCLASS, 'class'.freeze, @ts, @ts + 5)
           emit(:tLSHFT, '<<'.freeze,    @te - 2, @te)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 432 then
# line 1956 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(KEYWORDS)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 382 then
# line 2030 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :error, :no_dot_digit_literal
       end
                end
        when 422 then
# line 2090 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tCONSTANT)
            @cs = (arg_or_cmdarg);      begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 374 then
# line 2098 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1;  begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 311
                _goto_level = _again
                next
        end
  end
                end
        when 380 then
# line 2105 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 436;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 427 then
# line 1196 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    emit(:tIDENTIFIER)

    if !@static_env.nil? && @static_env.declared?(tok)
       @cs = 429;       begin
                p += 1
                _goto_level = _out
                next
        end

    else
       @cs = (arg_or_cmdarg);   begin
                p += 1
                _goto_level = _out
                next
        end

    end
   end
                end
        when 369 then
# line 2132 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 381 then
# line 2162 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 367 then
# line 2169 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 373 then
# line 2184 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] }
       end
                end
        when 61 then
# line 2030 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        diagnostic :error, :no_dot_digit_literal
       end
                end
        when 59 then
# line 2184 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] }
       end
                end
        when 62 then
# line 1 "NONE"
                begin
        case  @act
        when 124 then
        begin begin p = (( @te))-1; end

        if @lambda_stack.last == @paren_nest
          @lambda_stack.pop

          if tok == '{'.freeze
            emit(:tLAMBEG, '{'.freeze)
          else # 'do'
            emit(:kDO_LAMBDA, 'do'.freeze)
          end
        else
          if tok == '{'.freeze
            emit(:tLCURLY, '{'.freeze)
          else # 'do'
            emit_do
          end
        end

         @cs = 747;     begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 125 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 316;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 126 then
        begin begin p = (( @te))-1; end
 emit(:kCLASS, 'class'.freeze, @ts, @ts + 5)
           emit(:tLSHFT, '<<'.freeze,    @te - 2, @te)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 127 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 128 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 129 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 502;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 130 then
        begin begin p = (( @te))-1; end

        emit_table(KEYWORDS)

        if version?(18) && tok == 'not'.freeze
           @cs = 526;   begin
                p += 1
                _goto_level = _out
                next
        end

        else
           @cs = 457;   begin
                p += 1
                _goto_level = _out
                next
        end

        end
      end
        when 131 then
        begin begin p = (( @te))-1; end

        if version?(18)
          emit(:tIDENTIFIER)

          unless !@static_env.nil? && @static_env.declared?(tok)
             @cs = (arg_or_cmdarg);
          end
        else
          emit(:k__ENCODING__, '__ENCODING__'.freeze)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 132 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
                begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 133 then
        begin begin p = (( @te))-1; end

        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 135 then
        begin begin p = (( @te))-1; end

        if version?(18, 19, 20)
          diagnostic :error,
                     :trailing_in_number, { :character => tok(@te - 1, @te) },
                     range(@te - 1, @te)
        else
          emit(:tINTEGER, tok(@ts, @te - 1).to_i, @ts, @te - 1)
          p = p - 1;    begin
                p += 1
                _goto_level = _out
                next
        end

        end
      end
        when 136 then
        begin begin p = (( @te))-1; end

        if version?(18, 19, 20)
          diagnostic :error,
                     :trailing_in_number, { :character => tok(@te - 1, @te) },
                     range(@te - 1, @te)
        else
          emit(:tFLOAT, tok(@ts, @te - 1).to_f, @ts, @te - 1)
          p = p - 1;    begin
                p += 1
                _goto_level = _out
                next
        end

        end
      end
        when 137 then
        begin begin p = (( @te))-1; end

        digits = tok(@ts, @num_suffix_s)

        if version?(18, 19, 20)
          emit(:tFLOAT, Float(digits), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 139 then
        begin begin p = (( @te))-1; end
 emit(:tCONSTANT)
            @cs = (arg_or_cmdarg);      begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 143 then
        begin begin p = (( @te))-1; end

    emit(:tIDENTIFIER)

    if !@static_env.nil? && @static_env.declared?(tok)
       @cs = 429;       begin
                p += 1
                _goto_level = _out
                next
        end

    else
       @cs = (arg_or_cmdarg);   begin
                p += 1
                _goto_level = _out
                next
        end

    end
  end
        when 144 then
        begin begin p = (( @te))-1; end

        if tm == @te
          # Suffix was consumed, e.g. foo!
          emit(:tFID)
        else
          # Suffix was not consumed, e.g. foo!=
          emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm)
          p = tm - 1
        end
         @cs = 457;     begin
                p += 1
                _goto_level = _out
                next
        end

      end
end 
                        end
        when 76 then
# line 2196 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = tm - 1;     begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 440 then
# line 2199 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tNL, nil, @newline_s, @newline_s + 1)
           p = p - 1;  @cs = 161;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 441 then
# line 2199 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tNL, nil, @newline_s, @newline_s + 1)
           p = p - 1;  @cs = 161;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 73 then
# line 2199 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  emit(:tNL, nil, @newline_s, @newline_s + 1)
           p = p - 1;  @cs = 161;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 444 then
# line 2209 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit_comment(@eq_begin_s, @te)
                begin
                 @cs = 161
                _goto_level = _again
                next
        end

       end
                end
        when 443 then
# line 2217 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :fatal, :embedded_document, nil,
                   range(@eq_begin_s, @eq_begin_s + '=begin'.length)
       end
                end
        when 87 then
# line 2227 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  @eq_begin_s = @ts
                begin
                 @cs = 931
                _goto_level = _again
                next
        end
  end
                end
        when 2 then
# line 2231 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = pe - 3  end
                end
        when 79 then
# line 2234 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 747
                _goto_level = _again
                next
        end
  end
                end
        when 80 then
# line 512 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    # Sit at EOF indefinitely. #advance would return $eof each time.
    # This allows to feed the lexer more data if needed; this is only used
    # in tests.
    #
    # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs
    # below. This is due to the fact that scanner state at EOF is observed
    # by tests, and encapsulating it in a rule would break the introspection.
    p = p - 1;  begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 81 then
# line 2224 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 86 then
# line 2227 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  @eq_begin_s = @ts
                begin
                 @cs = 931
                _goto_level = _again
                next
        end
  end
                end
        when 85 then
# line 2234 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 747
                _goto_level = _again
                next
        end
  end
                end
        when 1 then
# line 2234 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 747
                _goto_level = _again
                next
        end
  end
                end
        when 71 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
        when 91 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 119 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 145 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 151 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 157 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 163 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
        when 233 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 1407 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        # Unlike expr_beg as invoked in the next rule, do not warn
        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 224 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 1466 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = tm - 1;     begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 216 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 1475 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 304 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 1724 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        escape = { " "  => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t',
                   "\v" => '\v', "\f" => '\f' }[@source_buffer.slice(@ts + 1)]
        diagnostic :warning, :invalid_escape_use, { :escape => escape }, range

        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 277 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 1839 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1
                begin
                 @cs = 161
                _goto_level = _again
                next
        end
  end
                end
        when 445 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 2209 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit_comment(@eq_begin_s, @te)
                begin
                 @cs = 161
                _goto_level = _again
                next
        end

       end
                end
        when 442 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 2214 "lib/parser/lexer.rl"
                begin
 @te = p+1
                end
        when 88 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 2227 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  @eq_begin_s = @ts
                begin
                 @cs = 931
                _goto_level = _again
                next
        end
  end
                end
        when 3 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 2231 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = pe - 3  end
                end
        when 399 then
# line 620 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tRATIONAL,  Rational(chars)) }              end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 398 then
# line 621 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, chars)) }            end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 400 then
# line 622 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Rational(chars))) }          end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 393 then
# line 626 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Float(chars))) }             end
# line 2062 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@ts, @num_suffix_s)

        if version?(18, 19, 20)
          emit(:tFLOAT, Float(digits), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 394 then
# line 630 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tRATIONAL,  Rational(chars)) }              end
# line 2062 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@ts, @num_suffix_s)

        if version?(18, 19, 20)
          emit(:tFLOAT, Float(digits), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 395 then
# line 631 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Rational(chars))) }          end
# line 2062 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@ts, @num_suffix_s)

        if version?(18, 19, 20)
          emit(:tFLOAT, Float(digits), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 114 then
# line 646 "lib/parser/lexer.rl"
                begin

    @escape = ""

    codepoints  = tok(@escape_s + 2, p - 1)
    codepoint_s = @escape_s + 2

    codepoints.split(/[ \t]/).each do |codepoint_str|
      codepoint = codepoint_str.to_i(16)

      if codepoint >= 0x110000
        diagnostic :error, :unicode_point_too_large, nil,
                   range(codepoint_s, codepoint_s + codepoint_str.length)
        break
      end

      @escape     += codepoint.chr(Encoding::UTF_8)
      codepoint_s += codepoint_str.length + 1
    end
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 140 then
# line 646 "lib/parser/lexer.rl"
                begin

    @escape = ""

    codepoints  = tok(@escape_s + 2, p - 1)
    codepoint_s = @escape_s + 2

    codepoints.split(/[ \t]/).each do |codepoint_str|
      codepoint = codepoint_str.to_i(16)

      if codepoint >= 0x110000
        diagnostic :error, :unicode_point_too_large, nil,
                   range(codepoint_s, codepoint_s + codepoint_str.length)
        break
      end

      @escape     += codepoint.chr(Encoding::UTF_8)
      codepoint_s += codepoint_str.length + 1
    end
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 325 then
# line 646 "lib/parser/lexer.rl"
                begin

    @escape = ""

    codepoints  = tok(@escape_s + 2, p - 1)
    codepoint_s = @escape_s + 2

    codepoints.split(/[ \t]/).each do |codepoint_str|
      codepoint = codepoint_str.to_i(16)

      if codepoint >= 0x110000
        diagnostic :error, :unicode_point_too_large, nil,
                   range(codepoint_s, codepoint_s + codepoint_str.length)
        break
      end

      @escape     += codepoint.chr(Encoding::UTF_8)
      codepoint_s += codepoint_str.length + 1
    end
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 98 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 124 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 309 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 101 then
# line 673 "lib/parser/lexer.rl"
                begin

    diagnostic :fatal, :invalid_escape
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 127 then
# line 673 "lib/parser/lexer.rl"
                begin

    diagnostic :fatal, :invalid_escape
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 312 then
# line 673 "lib/parser/lexer.rl"
                begin

    diagnostic :fatal, :invalid_escape
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 103 then
# line 692 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 129 then
# line 692 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 314 then
# line 692 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 100 then
# line 699 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100)             end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 126 then
# line 699 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100)             end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 311 then
# line 699 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100)             end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 116 then
# line 703 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s + 1, p).to_i(16))                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 142 then
# line 703 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s + 1, p).to_i(16))                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 327 then
# line 703 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s + 1, p).to_i(16))                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 111 then
# line 707 "lib/parser/lexer.rl"
                begin
 @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8)          end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 137 then
# line 707 "lib/parser/lexer.rl"
                begin
 @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8)          end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 322 then
# line 707 "lib/parser/lexer.rl"
                begin
 @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8)          end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 115 then
# line 711 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 141 then
# line 711 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 326 then
# line 711 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 110 then
# line 723 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 136 then
# line 723 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 321 then
# line 723 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 113 then
# line 734 "lib/parser/lexer.rl"
                begin

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 139 then
# line 734 "lib/parser/lexer.rl"
                begin

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 324 then
# line 734 "lib/parser/lexer.rl"
                begin

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 99 then
# line 760 "lib/parser/lexer.rl"
                begin

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 125 then
# line 760 "lib/parser/lexer.rl"
                begin

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 310 then
# line 760 "lib/parser/lexer.rl"
                begin

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 148 then
# line 766 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 153 then
# line 766 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 64 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
        when 28 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1421 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 30 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1437 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 32 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1465 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 177 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1296 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 196 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1314 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 204 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1346 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 31 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1475 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

       end
                end
        when 235 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1480 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 227 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1486 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 246 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1555 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 258 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1576 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 254 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1579 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 274 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1836 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 344 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1860 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 340 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1863 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
      if @in_kwarg
        p = p - 1;      begin
                 @cs = 755
                _goto_level = _again
                next
        end

      else
                begin
                 @cs = 161
                _goto_level = _again
                next
        end

      end
     end
                end
        when 353 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1891 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 350 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1894 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin        begin
                 @cs = 161
                _goto_level = _again
                next
        end
  end
                end
        when 426 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 2169 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 368 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 2172 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin        begin
                 @cs = 928
                _goto_level = _again
                next
        end
  end
                end
        when 82 then
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 2224 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 226 then
# line 977 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    current_literal = literal
    if current_literal
      current_literal.start_interp_brace
    end
                end
# line 1390 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @lambda_stack.last == @paren_nest
          p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end

        else
          emit(:tLCURLY, '{'.freeze, @te - 1, @te)
           @cs = 747;   begin
                p += 1
                _goto_level = _out
                next
        end

        end
       end
                end
        when 248 then
# line 977 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    current_literal = literal
    if current_literal
      current_literal.start_interp_brace
    end
                end
# line 1548 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLBRACE_ARG, '{'.freeze)
            @cs = 747;  end
                end
        when 336 then
# line 977 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    current_literal = literal
    if current_literal
      current_literal.start_interp_brace
    end
                end
# line 1751 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @lambda_stack.last == @paren_nest
          @lambda_stack.pop
          emit(:tLAMBEG, '{'.freeze)
        else
          emit(:tLBRACE, '{'.freeze)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 438 then
# line 977 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    current_literal = literal
    if current_literal
      current_literal.start_interp_brace
    end
                end
# line 1916 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @lambda_stack.last == @paren_nest
          @lambda_stack.pop

          if tok == '{'.freeze
            emit(:tLAMBEG, '{'.freeze)
          else # 'do'
            emit(:kDO_LAMBDA, 'do'.freeze)
          end
        else
          if tok == '{'.freeze
            emit(:tLCURLY, '{'.freeze)
          else # 'do'
            emit_do
          end
        end

         @cs = 747;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 439 then
# line 986 "lib/parser/lexer.rl"
                begin

    current_literal = literal
    if current_literal
      if current_literal.end_interp_brace_and_try_closing
        if version?(18, 19)
          emit(:tRCURLY, '}'.freeze, p - 1, p)
        else
          emit(:tSTRING_DEND, '}'.freeze, p - 1, p)
        end

        if current_literal.saved_herebody_s
          @herebody_s = current_literal.saved_herebody_s
        end

        p = p - 1;
         @cs = (stack_pop);
                begin
                p += 1
                _goto_level = _out
                next
        end

      end
    end
                end
# line 2136 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit_table(PUNCTUATION)
        @cond.lexpop; @cmdarg.lexpop

        if RBRACE_OR_RBRACK.include?(tok)
           @cs = 494;
        else # )
          # fnext expr_endfn; ?
        end

                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 66 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
        when 69 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
        when 180 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1296 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 195 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1314 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 207 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1346 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 229 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1483 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin        begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 244 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1555 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 256 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1576 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 280 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1836 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 342 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1860 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 352 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1891 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 372 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2169 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 84 then
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2224 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 201 then
# line 1152 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1336 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tFID, tok(@ts, tm), @ts, tm)
            @cs = (arg_or_cmdarg); p = tm - 1;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 292 then
# line 1152 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1685 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 265 then
# line 1152 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1824 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 365 then
# line 1152 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1 "NONE"
                begin
        case  @act
        when 124 then
        begin begin p = (( @te))-1; end

        if @lambda_stack.last == @paren_nest
          @lambda_stack.pop

          if tok == '{'.freeze
            emit(:tLAMBEG, '{'.freeze)
          else # 'do'
            emit(:kDO_LAMBDA, 'do'.freeze)
          end
        else
          if tok == '{'.freeze
            emit(:tLCURLY, '{'.freeze)
          else # 'do'
            emit_do
          end
        end

         @cs = 747;     begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 125 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 316;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 126 then
        begin begin p = (( @te))-1; end
 emit(:kCLASS, 'class'.freeze, @ts, @ts + 5)
           emit(:tLSHFT, '<<'.freeze,    @te - 2, @te)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 127 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 128 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 129 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 502;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 130 then
        begin begin p = (( @te))-1; end

        emit_table(KEYWORDS)

        if version?(18) && tok == 'not'.freeze
           @cs = 526;   begin
                p += 1
                _goto_level = _out
                next
        end

        else
           @cs = 457;   begin
                p += 1
                _goto_level = _out
                next
        end

        end
      end
        when 131 then
        begin begin p = (( @te))-1; end

        if version?(18)
          emit(:tIDENTIFIER)

          unless !@static_env.nil? && @static_env.declared?(tok)
             @cs = (arg_or_cmdarg);
          end
        else
          emit(:k__ENCODING__, '__ENCODING__'.freeze)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 132 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
                begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 133 then
        begin begin p = (( @te))-1; end

        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 135 then
        begin begin p = (( @te))-1; end

        if version?(18, 19, 20)
          diagnostic :error,
                     :trailing_in_number, { :character => tok(@te - 1, @te) },
                     range(@te - 1, @te)
        else
          emit(:tINTEGER, tok(@ts, @te - 1).to_i, @ts, @te - 1)
          p = p - 1;    begin
                p += 1
                _goto_level = _out
                next
        end

        end
      end
        when 136 then
        begin begin p = (( @te))-1; end

        if version?(18, 19, 20)
          diagnostic :error,
                     :trailing_in_number, { :character => tok(@te - 1, @te) },
                     range(@te - 1, @te)
        else
          emit(:tFLOAT, tok(@ts, @te - 1).to_f, @ts, @te - 1)
          p = p - 1;    begin
                p += 1
                _goto_level = _out
                next
        end

        end
      end
        when 137 then
        begin begin p = (( @te))-1; end

        digits = tok(@ts, @num_suffix_s)

        if version?(18, 19, 20)
          emit(:tFLOAT, Float(digits), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 139 then
        begin begin p = (( @te))-1; end
 emit(:tCONSTANT)
            @cs = (arg_or_cmdarg);      begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 143 then
        begin begin p = (( @te))-1; end

    emit(:tIDENTIFIER)

    if !@static_env.nil? && @static_env.declared?(tok)
       @cs = 429;       begin
                p += 1
                _goto_level = _out
                next
        end

    else
       @cs = (arg_or_cmdarg);   begin
                p += 1
                _goto_level = _out
                next
        end

    end
  end
        when 144 then
        begin begin p = (( @te))-1; end

        if tm == @te
          # Suffix was consumed, e.g. foo!
          emit(:tFID)
        else
          # Suffix was not consumed, e.g. foo!=
          emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm)
          p = tm - 1
        end
         @cs = 457;     begin
                p += 1
                _goto_level = _out
                next
        end

      end
end 
                        end
        when 202 then
# line 1153 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1336 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tFID, tok(@ts, tm), @ts, tm)
            @cs = (arg_or_cmdarg); p = tm - 1;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 293 then
# line 1153 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1685 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 267 then
# line 1153 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1824 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 366 then
# line 1153 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 2112 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if tm == @te
          # Suffix was consumed, e.g. foo!
          emit(:tFID)
        else
          # Suffix was not consumed, e.g. foo!=
          emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm)
          p = tm - 1
        end
         @cs = 457;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 294 then
# line 1158 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1685 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 268 then
# line 1158 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1824 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 295 then
# line 1159 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1685 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 269 then
# line 1159 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1824 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 299 then
# line 1160 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1685 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 272 then
# line 1160 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1824 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 298 then
# line 1161 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1685 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 271 then
# line 1161 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1 "NONE"
                begin
        case  @act
        when 103 then
        begin begin p = (( @te))-1; end
 emit_table(PUNCTUATION_BEGIN)
                begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 104 then
        begin begin p = (( @te))-1; end
 emit(:kRESCUE, 'rescue'.freeze, @ts, tm)
           p = tm - 1
            @cs = 502;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 105 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS_BEGIN)
            @cs = 747;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 107 then
        begin begin p = (( @te))-1; end
 p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
 end
        when 108 then
        begin begin p = (( @te))-1; end

    emit(:tIDENTIFIER)

    if !@static_env.nil? && @static_env.declared?(tok)
       @cs = 429;       begin
                p += 1
                _goto_level = _out
                next
        end

    else
       @cs = (arg_or_cmdarg);   begin
                p += 1
                _goto_level = _out
                next
        end

    end
  end
        when 111 then
        begin begin p = (( @te))-1; end
 p = @ts - 1;   begin
                 @cs = 755
                _goto_level = _again
                next
        end
 end
end 
                        end
        when 296 then
# line 1162 "lib/parser/lexer.rl"
                begin
 tm = p - 3             end
# line 1685 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 270 then
# line 1162 "lib/parser/lexer.rl"
                begin
 tm = p - 3             end
# line 1824 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 297 then
# line 1167 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1685 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 421 then
# line 1172 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 2094 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tCONSTANT, tok(@ts, tm), @ts, tm)
           p = tm - 1;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 225 then
# line 1178 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)
                end
# line 1384 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLBRACK, '['.freeze, @te - 1, @te)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 328 then
# line 1178 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)
                end
# line 1763 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLBRACK, '['.freeze)
                begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 424 then
# line 1178 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)
                end
# line 2158 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLBRACK2, '['.freeze)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 217 then
# line 1185 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    @paren_nest += 1
                end
# line 1365 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if version?(18)
          emit(:tLPAREN2, '('.freeze, @te - 1, @te)
           @cs = 747;   begin
                p += 1
                _goto_level = _out
                next
        end

        else
          emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te)
           @cs = 526;   begin
                p += 1
                _goto_level = _out
                next
        end

        end
       end
                end
        when 230 then
# line 1185 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    @paren_nest += 1
                end
# line 1378 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLPAREN2, '('.freeze)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 238 then
# line 1185 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    @paren_nest += 1
                end
# line 1502 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te)
        if version?(18)
           @cs = 747;   begin
                p += 1
                _goto_level = _out
                next
        end

        else
           @cs = 526;   begin
                p += 1
                _goto_level = _out
                next
        end

        end
       end
                end
        when 285 then
# line 1185 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    @paren_nest += 1
                end
# line 1768 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLPAREN, '('.freeze)
                begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 377 then
# line 1185 "lib/parser/lexer.rl"
                begin

    @cond.push(false); @cmdarg.push(false)

    @paren_nest += 1
                end
# line 2132 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 526;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 378 then
# line 1191 "lib/parser/lexer.rl"
                begin

    @paren_nest -= 1
                end
# line 2136 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit_table(PUNCTUATION)
        @cond.lexpop; @cmdarg.lexpop

        if RBRACE_OR_RBRACK.include?(tok)
           @cs = 494;
        else # )
          # fnext expr_endfn; ?
        end

                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 54 then
# line 1651 "lib/parser/lexer.rl"
                begin
 heredoc_e      = p             end
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
        when 300 then
# line 1652 "lib/parser/lexer.rl"
                begin
 new_herebody_s = p             end
# line 1653 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        tok(@ts, heredoc_e) =~ /^<<(-?)(~?)(["'`]?)(.*)\3$/

        indent      = !$1.empty? || !$2.empty?
        dedent_body = !$2.empty?
        type        =  $3.empty? ? '<<"'.freeze : ('<<'.freeze + $3)
        delimiter   =  $4

        if dedent_body && version?(18, 19, 20, 21, 22)
          emit(:tLSHFT, '<<'.freeze, @ts, @ts + 2)
          p = @ts + 1
           @cs = 526;   begin
                p += 1
                _goto_level = _out
                next
        end

        else
           @cs = (push_literal(type, delimiter, @ts, heredoc_e, indent, dedent_body));

          @herebody_s ||= new_herebody_s
          p = @herebody_s - 1
        end
       end
                end
        when 305 then
# line 1705 "lib/parser/lexer.rl"
                begin
 @escape = nil          end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 332 then
# line 1778 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1779 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:kRESCUE, 'rescue'.freeze, @ts, tm)
           p = tm - 1
            @cs = 502;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 412 then
# line 1996 "lib/parser/lexer.rl"
                begin
 @num_base = 16; @num_digits_s = p              end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 406 then
# line 1997 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = p              end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 409 then
# line 1998 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = p              end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 403 then
# line 1999 "lib/parser/lexer.rl"
                begin
 @num_base = 2;  @num_digits_s = p              end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 418 then
# line 2000 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 387 then
# line 2001 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 419 then
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
        when 75 then
# line 2195 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 2196 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = tm - 1;     begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 8 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
        when 186 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1255 "lib/parser/lexer.rl"
                begin
 @act = 31;             end
        when 173 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1259 "lib/parser/lexer.rl"
                begin
 @act = 32;             end
        when 169 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1263 "lib/parser/lexer.rl"
                begin
 @act = 33;             end
        when 24 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1425 "lib/parser/lexer.rl"
                begin
 @act = 59;             end
        when 219 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1438 "lib/parser/lexer.rl"
                begin
 @act = 60;             end
        when 25 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1475 "lib/parser/lexer.rl"
                begin
 @act = 65;             end
        when 212 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1480 "lib/parser/lexer.rl"
                begin
 @act = 66;             end
        when 239 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1512 "lib/parser/lexer.rl"
                begin
 @act = 72;             end
        when 43 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1525 "lib/parser/lexer.rl"
                begin
 @act = 73;             end
        when 260 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1570 "lib/parser/lexer.rl"
                begin
 @act = 80;             end
        when 249 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1574 "lib/parser/lexer.rl"
                begin
 @act = 81;             end
        when 263 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1773 "lib/parser/lexer.rl"
                begin
 @act = 103;            end
        when 331 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1779 "lib/parser/lexer.rl"
                begin
 @act = 104;            end
        when 330 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1785 "lib/parser/lexer.rl"
                begin
 @act = 105;            end
        when 56 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1824 "lib/parser/lexer.rl"
                begin
 @act = 107;            end
        when 261 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1196 "lib/parser/lexer.rl"
                begin
 @act = 108;            end
        when 264 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1852 "lib/parser/lexer.rl"
                begin
 @act = 111;            end
        when 434 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1916 "lib/parser/lexer.rl"
                begin
 @act = 124;            end
        when 429 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1941 "lib/parser/lexer.rl"
                begin
 @act = 125;            end
        when 437 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1951 "lib/parser/lexer.rl"
                begin
 @act = 127;            end
        when 430 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1956 "lib/parser/lexer.rl"
                begin
 @act = 128;            end
        when 431 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1960 "lib/parser/lexer.rl"
                begin
 @act = 129;            end
        when 436 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1964 "lib/parser/lexer.rl"
                begin
 @act = 130;            end
        when 428 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1975 "lib/parser/lexer.rl"
                begin
 @act = 131;            end
        when 423 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1989 "lib/parser/lexer.rl"
                begin
 @act = 132;            end
        when 359 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2003 "lib/parser/lexer.rl"
                begin
 @act = 133;            end
        when 389 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2047 "lib/parser/lexer.rl"
                begin
 @act = 136;            end
        when 63 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2062 "lib/parser/lexer.rl"
                begin
 @act = 137;            end
        when 362 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2090 "lib/parser/lexer.rl"
                begin
 @act = 139;            end
        when 354 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1196 "lib/parser/lexer.rl"
                begin
 @act = 143;            end
        when 364 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2112 "lib/parser/lexer.rl"
                begin
 @act = 144;            end
        when 154 then
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 877 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
    current_literal = literal
    if @te == pe
      diagnostic :fatal, :string_eof, nil,
                 range(current_literal.str_s, current_literal.str_s + 1)
    end

    if current_literal.heredoc?
      line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)

      if version?(18, 19, 20)
        # See ruby:c48b4209c
        line = line.gsub(/\r.*$/, ''.freeze)
      end

      # Try ending the heredoc with the complete most recently
      # scanned line. @herebody_s always refers to the start of such line.
      if current_literal.nest_and_try_closing(line, @herebody_s, @ts)
        # Adjust @herebody_s to point to the next line.
        @herebody_s = @te

        # Continue regular lexing after the heredoc reference (<<END).
        p = current_literal.heredoc_e - 1
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      else
        # Calculate indentation level for <<~HEREDOCs.
        current_literal.infer_indent_level(line)

        # Ditto.
        @herebody_s = @te
      end
    else
      # Try ending the literal with a newline.
      if current_literal.nest_and_try_closing(tok, @ts, @te)
         @cs = (pop_literal);   begin
                p += 1
                _goto_level = _out
                next
        end

      end

      if @herebody_s
        # This is a regular literal intertwined with a heredoc. Like:
        #
        #     p <<-foo+"1
        #     bar
        #     foo
        #     2"
        #
        # which, incidentally, evaluates to "bar\n1\n2".
        p = @herebody_s - 1
        @herebody_s = nil
      end
    end

    if current_literal.words? && !eof_codepoint?(@source_pts[p])
      current_literal.extend_space @ts, @te
    else
      # A literal newline is appended if the heredoc was _not_ closed
      # this time (see fbreak above). See also Literal#nest_and_try_closing
      # for rationale of calling #flush_string here.
      current_literal.extend_string tok, @ts, @te
      current_literal.flush_string
    end
   end
                end
# line 766 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
        when 104 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 130 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 315 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 109 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 135 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 320 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 108 then
# line 687 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 134 then
# line 687 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 319 then
# line 687 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 106 then
# line 692 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 132 then
# line 692 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 317 then
# line 692 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 102 then
# line 693 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 128 then
# line 693 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 313 then
# line 693 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 112 then
# line 723 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 734 "lib/parser/lexer.rl"
                begin

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 138 then
# line 723 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 734 "lib/parser/lexer.rl"
                begin

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 323 then
# line 723 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 734 "lib/parser/lexer.rl"
                begin

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 96 then
# line 766 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
# line 760 "lib/parser/lexer.rl"
                begin

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 123 then
# line 766 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
# line 760 "lib/parser/lexer.rl"
                begin

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 308 then
# line 766 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
# line 760 "lib/parser/lexer.rl"
                begin

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 67 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
        when 179 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1296 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 194 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1314 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 206 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1346 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 228 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1483 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin        begin
                 @cs = 755
                _goto_level = _again
                next
        end
  end
                end
        when 243 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1555 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 255 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1576 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 279 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1836 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 341 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1860 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 351 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1891 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 371 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2169 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 83 then
# line 1108 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2224 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 414 then
# line 2000 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
        when 384 then
# line 2001 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
        when 396 then
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 391 then
# line 2059 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 625 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tFLOAT,     Float(chars)) }                 end
# line 2062 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@ts, @num_suffix_s)

        if version?(18, 19, 20)
          emit(:tFLOAT, Float(digits), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 388 then
# line 2060 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 625 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tFLOAT,     Float(chars)) }                 end
# line 2062 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@ts, @num_suffix_s)

        if version?(18, 19, 20)
          emit(:tFLOAT, Float(digits), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits)
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 234 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 486 "lib/parser/lexer.rl"
                begin

    # Record position of a newline for precise location reporting on tNL
    # tokens.
    #
    # This action is embedded directly into c_nl, as it is idempotent and
    # there are no cases when we need to skip it.
    @newline_s = p
                end
# line 1480 "lib/parser/lexer.rl"
                begin
 @act = 66;             end
        when 33 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1475 "lib/parser/lexer.rl"
                begin
 @act = 65;             end
        when 44 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1525 "lib/parser/lexer.rl"
                begin
 @act = 73;             end
        when 70 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1111 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1945 "lib/parser/lexer.rl"
                begin
 @act = 126;            end
        when 35 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1437 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1438 "lib/parser/lexer.rl"
                begin
 @act = 60;             end
        when 334 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1778 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1824 "lib/parser/lexer.rl"
                begin
 @act = 107;            end
        when 333 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1778 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1196 "lib/parser/lexer.rl"
                begin
 @act = 108;            end
        when 415 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2000 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2003 "lib/parser/lexer.rl"
                begin
 @act = 133;            end
        when 107 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 133 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 318 then
# line 666 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]
    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 105 then
# line 693 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 131 then
# line 693 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 839 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    current_literal = literal
    # Get the first character after the backslash.
    escaped_char = @source_buffer.slice(@escape_s).chr

    if current_literal.munge_escape? escaped_char
      # If this particular literal uses this character as an opening
      # or closing delimiter, it is an escape sequence for that
      # particular character. Write it without the backslash.

      if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char)
        # Regular expressions should include escaped delimiters in their
        # escaped form, except when the escaped character is
        # a closing delimiter but not a regexp metacharacter.
        #
        # The backslash itself cannot be used as a closing delimiter
        # at the same time as an escape symbol, but it is always munged,
        # so this branch also executes for the non-closing-delimiter case
        # for the backslash.
        current_literal.extend_string(tok, @ts, @te)
      else
        current_literal.extend_string(escaped_char, @ts, @te)
      end
    else
      # It does not. So this is an actual escape sequence, yay!
      if current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed.
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      else
        current_literal.extend_string(@escape || tok, @ts, @te)
      end
    end
   end
                end
        when 316 then
# line 693 "lib/parser/lexer.rl"
                begin
 @escape = @source_buffer.slice(p - 1).chr              end
# line 677 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 681 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 1707 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          if defined?(Encoding)
            emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord)
          else
            emit(:tINTEGER, value[0].ord)
          end
        else
          emit(:tCHARACTER, value)
        end

         @cs = 755;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 410 then
# line 1996 "lib/parser/lexer.rl"
                begin
 @num_base = 16; @num_digits_s = p              end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 404 then
# line 1997 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = p              end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 407 then
# line 1998 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = p              end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 401 then
# line 1999 "lib/parser/lexer.rl"
                begin
 @num_base = 2;  @num_digits_s = p              end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 413 then
# line 2000 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 383 then
# line 2001 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2003 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        digits = tok(@num_digits_s, @num_suffix_s)

        if digits.end_with? '_'.freeze
          diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
                     range(@te - 1, @te)
        elsif digits.empty? && @num_base == 8 && version?(18)
          # 1.8 did not raise an error on 0o.
          digits = '0'.freeze
        elsif digits.empty?
          diagnostic :error, :empty_numeric
        elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
          invalid_s = @num_digits_s + invalid_idx
          diagnostic :error, :invalid_octal, nil,
                     range(invalid_s, invalid_s + 1)
        end

        if version?(18, 19, 20)
          emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
          p = @num_suffix_s - 1
        else
          @num_xfrm.call(digits.to_i(@num_base))
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 29 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 806 "lib/parser/lexer.rl"
                begin

    # After every heredoc was parsed, @herebody_s contains the
    # position of next token after all heredocs.
    if @herebody_s
      p = @herebody_s
      @herebody_s = nil
    end
                end
# line 1437 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1438 "lib/parser/lexer.rl"
                begin
 @act = 60;             end
        when 420 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2035 "lib/parser/lexer.rl"
                begin
 @act = 135;            end
        when 416 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2000 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2035 "lib/parser/lexer.rl"
                begin
 @act = 135;            end
        when 386 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2001 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
# line 2002 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 619 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2035 "lib/parser/lexer.rl"
                begin
 @act = 135;            end
# line 20792 "lib/parser/lexer.rb"
        end
        end
        end
        if _goto_level <= _again
        case _lex_to_state_actions[ @cs] 
        when 77 then
# line 1 "NONE"
                begin
 @ts = nil;             end
# line 20802 "lib/parser/lexer.rb"
        end

        if  @cs == 0
                _goto_level = _out
                next
        end
        p += 1
        if p != pe
                _goto_level = _resume
                next
        end
        end
        if _goto_level <= _test_eof
        if p == eof
        if _lex_eof_trans[ @cs] > 0
                _trans = _lex_eof_trans[ @cs] - 1;
                _goto_level = _eof_trans
                next;
        end
        end

        end
        if _goto_level <= _out
                break
        end
end
        end

# line 282 "lib/parser/lexer.rl"
    # %

    @p = p

    if @token_queue.any?
      @token_queue.shift
    elsif @cs == klass.lex_error
      [ false, [ '$error'.freeze, range(p - 1, p) ] ]
    else
      eof = @source_pts.size
      [ false, [ '$eof'.freeze,   range(eof, eof) ] ]
    end
  end
dedent_level() click to toggle source
# File lib/parser/lexer.rb, line 10756
def dedent_level
  # We erase @dedent_level as a precaution to avoid accidentally
  # using a stale value.
  dedent_level, @dedent_level = @dedent_level, nil
  dedent_level
end
encoding() click to toggle source
# File lib/parser/lexer.rb, line 10706
def encoding
  @source_buffer.source.encoding
end
pop_cmdarg() click to toggle source
# File lib/parser/lexer.rb, line 10743
def pop_cmdarg
  @cmdarg = @cmdarg_stack.pop
end
pop_cond() click to toggle source
# File lib/parser/lexer.rb, line 10752
def pop_cond
  @cond = @cond_stack.pop
end
push_cmdarg() click to toggle source
# File lib/parser/lexer.rb, line 10738
def push_cmdarg
  @cmdarg_stack.push(@cmdarg)
  @cmdarg = StackState.new("cmdarg.#{@cmdarg_stack.count}")
end
push_cond() click to toggle source
# File lib/parser/lexer.rb, line 10747
def push_cond
  @cond_stack.push(@cond)
  @cond = StackState.new("cond.#{@cond_stack.count}")
end
reset(reset_state=true) click to toggle source
# File lib/parser/lexer.rb, line 10620
def reset(reset_state=true)
  # Ragel state:
  if reset_state
    # Unit tests set state prior to resetting lexer.
    @cs     = self.class.lex_en_line_begin

    @cond   = StackState.new('cond')
    @cmdarg = StackState.new('cmdarg')
    @cond_stack   = []
    @cmdarg_stack = []
  end

  @force_utf32   = false # Set to true by some tests

  @source_pts    = nil # @source as a codepoint array

  @p             = 0   # stream position (saved manually in #advance)
  @ts            = nil # token start
  @te            = nil # token end
  @act           = 0   # next action

  @stack         = []  # state stack
  @top           = 0   # state stack top pointer

  # Lexer state:
  @token_queue   = []
  @literal_stack = []

  @eq_begin_s    = nil # location of last encountered =begin
  @sharp_s       = nil # location of last encountered #

  @newline_s     = nil # location of last encountered newline

  @num_base      = nil # last numeric base
  @num_digits_s  = nil # starting position of numeric digits
  @num_suffix_s  = nil # starting position of numeric suffix
  @num_xfrm      = nil # numeric suffix-induced transformation

  @escape_s      = nil # starting position of current sequence
  @escape        = nil # last escaped sequence, as string

  @herebody_s    = nil # starting position of current heredoc line

  # Ruby 1.9 ->() lambdas emit a distinct token if do/{ is
  # encountered after a matching closing parenthesis.
  @paren_nest    = 0
  @lambda_stack  = []

  # After encountering the closing line of <<~SQUIGGLY_HEREDOC,
  # we store the indentation level and give it out to the parser
  # on request. It is not possible to infer indentation level just
  # from the AST because escape sequences such as `\ ` or `\t` are
  # expanded inside the lexer, but count as non-whitespace for
  # indentation purposes.
  @dedent_level  = nil

  # If the lexer is in `command state' (aka expr_value)
  # at the entry to #advance, it will transition to expr_cmdarg
  # instead of expr_arg at certain points.
  @command_state = false

  # True at the end of "def foo a:"
  @in_kwarg      = false
end
source_buffer=(source_buffer) click to toggle source
# File lib/parser/lexer.rb, line 10685
def source_buffer=(source_buffer)
  @source_buffer = source_buffer

  if @source_buffer
    source = @source_buffer.source

    if defined?(Encoding) && source.encoding == Encoding::UTF_8
      @source_pts = source.unpack('U*')
    else
      @source_pts = source.unpack('C*')
    end

    if @source_pts[0] == 0xfeff
      # Skip byte order mark.
      @p = 1
    end
  else
    @source_pts = nil
  end
end
state() click to toggle source
# File lib/parser/lexer.rb, line 10730
def state
  LEX_STATES.invert.fetch(@cs, @cs)
end
state=(state) click to toggle source
# File lib/parser/lexer.rb, line 10734
def state=(state)
  @cs = LEX_STATES.fetch(state)
end

Protected Instance Methods

arg_or_cmdarg() click to toggle source
# File lib/parser/lexer.rb, line 20904
def arg_or_cmdarg
  if @command_state
    self.class.lex_en_expr_cmdarg
  else
    self.class.lex_en_expr_arg
  end
end
diagnostic(type, reason, arguments=nil, location=range, highlights=[]) click to toggle source
# File lib/parser/lexer.rb, line 20924
def diagnostic(type, reason, arguments=nil, location=range, highlights=[])
  @diagnostics.process(
      Parser::Diagnostic.new(type, reason, arguments, location, highlights))
end
emit(type, value = tok, s = @ts, e = @te) click to toggle source
# File lib/parser/lexer.rb, line 20878
def emit(type, value = tok, s = @ts, e = @te)
  token = [ type, [ value, range(s, e) ] ]

  @token_queue.push(token)

  @tokens.push(token) if @tokens

  token
end
emit_comment(s = @ts, e = @te) click to toggle source
# File lib/parser/lexer.rb, line 20912
def emit_comment(s = @ts, e = @te)
  if @comments
    @comments.push(Parser::Source::Comment.new(range(s, e)))
  end

  if @tokens
    @tokens.push([ :tCOMMENT, [ tok(s, e), range(s, e) ] ])
  end

  nil
end
emit_do(do_block=false) click to toggle source
# File lib/parser/lexer.rb, line 20894
def emit_do(do_block=false)
  if @cond.active?
    emit(:kDO_COND, 'do'.freeze)
  elsif @cmdarg.active? || do_block
    emit(:kDO_BLOCK, 'do'.freeze)
  else
    emit(:kDO, 'do'.freeze)
  end
end
emit_table(table, s = @ts, e = @te) click to toggle source
# File lib/parser/lexer.rb, line 20888
def emit_table(table, s = @ts, e = @te)
  value = tok(s, e)

  emit(table[value], value, s, e)
end
encode_escape(ord) click to toggle source
# File lib/parser/lexer.rb, line 20861
def encode_escape(ord)
  ord.chr.force_encoding(@source_buffer.source.encoding)
end
eof_codepoint?(point) click to toggle source
# File lib/parser/lexer.rb, line 20847
def eof_codepoint?(point)
  [0x04, 0x1a, 0x00].include? point
end
literal() click to toggle source
# File lib/parser/lexer.rb, line 20958
def literal
  @literal_stack.last
end
pop_literal() click to toggle source
# File lib/parser/lexer.rb, line 20962
def pop_literal
  old_literal = @literal_stack.pop

  @dedent_level = old_literal.dedent_level

  if old_literal.type == :tREGEXP_BEG
    # Fetch modifiers.
    self.class.lex_en_regexp_modifiers
  else
    self.class.lex_en_expr_end
  end
end
push_literal(*args) click to toggle source

LITERAL STACK ===

# File lib/parser/lexer.rb, line 20933
def push_literal(*args)
  new_literal = Literal.new(self, *args)
  @literal_stack.push(new_literal)

  if new_literal.words?
    if new_literal.interpolate?
      self.class.lex_en_interp_words
    else
      self.class.lex_en_plain_words
    end
  elsif new_literal.backslash_delimited?
    if new_literal.interpolate?
      self.class.lex_en_interp_backslash_delimited
    else
      self.class.lex_en_plain_backslash_delimited
    end
  else
    if new_literal.interpolate?
      self.class.lex_en_interp_string
    else
      self.class.lex_en_plain_string
    end
  end
end
range(s = @ts, e = @te) click to toggle source
# File lib/parser/lexer.rb, line 20874
def range(s = @ts, e = @te)
  Parser::Source::Range.new(@source_buffer, s, e)
end
stack_pop() click to toggle source
# File lib/parser/lexer.rb, line 20855
def stack_pop
  @top -= 1
  @stack[@top]
end
tok(s = @ts, e = @te) click to toggle source
# File lib/parser/lexer.rb, line 20870
def tok(s = @ts, e = @te)
  @source_buffer.slice(s...e)
end
version?(*versions) click to toggle source
# File lib/parser/lexer.rb, line 20851
def version?(*versions)
  versions.include?(@version)
end