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
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_backslash_delimited_words[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_backslash_delimited_words[RW]
lex_en_plain_string[RW]
lex_en_plain_words[RW]
lex_en_regexp_modifiers[RW]
lex_error[RW]
lex_start[RW]
cmdarg[RW]
cmdarg_stack[R]
command_start[RW]
comments[RW]
cond[RW]
cond_stack[R]
context[RW]
diagnostics[RW]
force_utf32[RW]
in_kwarg[RW]
lambda_stack[R]
paren_nest[R]
source_buffer[R]
static_env[RW]
tokens[RW]

Public Class Methods

new(version) click to toggle source
# File lib/parser/lexer.rb, line 10808
def initialize(version)
  @version    = version
  @static_env = nil
  @context    = 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 10966
  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

    cmd_state = @command_start
    @command_start = false

    
# line 10991 "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 97 then
# line 1 "NONE"
                begin
 @ts = p
                end
# line 11019 "lib/parser/lexer.rb"
        end
        _keys =  @cs << 1
        _inds = _lex_index_offsets[ @cs]
        _slen = _lex_key_spans[ @cs]
        _wide = ( (@source_pts[p] || 0))
        _trans = if (   _slen > 0 && 
                        _lex_trans_keys[_keys] <= _wide && 
                        _wide <= _lex_trans_keys[_keys + 1] 
                    ) then
                        _lex_indicies[ _inds + _wide - _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 28 then
# line 501 "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 117 then
# line 822 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
        when 29 then
# line 862 "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 59 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
        when 63 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
        when 304 then
# line 1266 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 36 then
# line 1547 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 38 then
# line 1567 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 40 then
# line 1595 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 70 then
# line 1787 "lib/parser/lexer.rl"
                begin
 heredoc_e      = p             end
        when 343 then
# line 1879 "lib/parser/lexer.rl"
                begin
 tm = p - 1; diag_msg = :ivar_name              end
        when 346 then
# line 1880 "lib/parser/lexer.rl"
                begin
 tm = p - 2; diag_msg = :cvar_name              end
        when 354 then
# line 1900 "lib/parser/lexer.rl"
                begin
 @escape = nil          end
        when 383 then
# line 1989 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 302 then
# line 2077 "lib/parser/lexer.rl"
                begin
 ident_tok = tok; ident_ts = @ts; ident_te = @te;               end
        when 470 then
# line 2263 "lib/parser/lexer.rl"
                begin
 @num_base = 16; @num_digits_s = p              end
        when 464 then
# line 2264 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = p              end
        when 467 then
# line 2265 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = p              end
        when 461 then
# line 2266 "lib/parser/lexer.rl"
                begin
 @num_base = 2;  @num_digits_s = p              end
        when 476 then
# line 2267 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
        when 438 then
# line 2268 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
        when 453 then
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 446 then
# line 2326 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 443 then
# line 2327 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 88 then
# line 2515 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 7 then
# line 1 "NONE"
                begin
 @te = p+1
                end
        when 113 then
# line 1099 "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
    @command_start = true
     @cs = 773;
        begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 5 then
# line 1025 "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 = 328
                _goto_level = _again
                next
        end

   end
                end
        when 109 then
# line 950 "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 108 then
# line 871 "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 = 766;
      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 115 then
# line 1041 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    if @version >= 27
      literal.extend_string(tok, @ts, @te)
    else
      message = tok.start_with?('#@@') ? :cvar_name : :ivar_name
      diagnostic :error, message, { :name => tok(@ts + 1, @te) }, range(@ts + 1, @te)
    end
   end
                end
        when 114 then
# line 1025 "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 = 328
                _goto_level = _again
                next
        end

   end
                end
        when 111 then
# line 1012 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    literal.extend_space @ts, @te
   end
                end
        when 112 then
# line 871 "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 = 766;
      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 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 871 "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 = 766;
      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 142 then
# line 1099 "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
    @command_start = true
     @cs = 773;
        begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 10 then
# line 1025 "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 = 328
                _goto_level = _again
                next
        end

   end
                end
        when 139 then
# line 950 "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 138 then
# line 871 "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 = 766;
      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 1041 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    if @version >= 27
      literal.extend_string(tok, @ts, @te)
    else
      message = tok.start_with?('#@@') ? :cvar_name : :ivar_name
      diagnostic :error, message, { :name => tok(@ts + 1, @te) }, range(@ts + 1, @te)
    end
   end
                end
        when 143 then
# line 1025 "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 = 328
                _goto_level = _again
                next
        end

   end
                end
        when 141 then
# line 871 "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 = 766;
      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 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 871 "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 = 766;
      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 167 then
# line 950 "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 166 then
# line 871 "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 = 766;
      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 169 then
# line 1012 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    literal.extend_space @ts, @te
   end
                end
        when 170 then
# line 871 "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 = 766;
      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 173 then
# line 950 "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 172 then
# line 871 "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 = 766;
      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 175 then
# line 871 "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 = 766;
      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 182 then
# line 1099 "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
    @command_start = true
     @cs = 773;
        begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 13 then
# line 1025 "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 = 328
                _goto_level = _again
                next
        end

   end
                end
        when 179 then
# line 950 "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 178 then
# line 871 "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 = 766;
      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 184 then
# line 1041 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    if @version >= 27
      literal.extend_string(tok, @ts, @te)
    else
      message = tok.start_with?('#@@') ? :cvar_name : :ivar_name
      diagnostic :error, message, { :name => tok(@ts + 1, @te) }, range(@ts + 1, @te)
    end
   end
                end
        when 183 then
# line 1025 "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 = 328
                _goto_level = _again
                next
        end

   end
                end
        when 181 then
# line 871 "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 = 766;
      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 871 "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 = 766;
      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 186 then
# line 950 "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 185 then
# line 871 "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 = 766;
      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 193 then
# line 1099 "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
    @command_start = true
     @cs = 773;
        begin
                p += 1
                _goto_level = _out
                next
        end

   end
                end
        when 15 then
# line 1025 "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 = 328
                _goto_level = _again
                next
        end

   end
                end
        when 189 then
# line 950 "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 188 then
# line 871 "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 = 766;
      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 195 then
# line 1041 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    if @version >= 27
      literal.extend_string(tok, @ts, @te)
    else
      message = tok.start_with?('#@@') ? :cvar_name : :ivar_name
      diagnostic :error, message, { :name => tok(@ts + 1, @te) }, range(@ts + 1, @te)
    end
   end
                end
        when 194 then
# line 1025 "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 = 328
                _goto_level = _again
                next
        end

   end
                end
        when 191 then
# line 1012 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    literal.extend_space @ts, @te
   end
                end
        when 192 then
# line 871 "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 = 766;
      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 14 then
# line 871 "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 = 766;
      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 197 then
# line 950 "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 196 then
# line 871 "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 = 766;
      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 199 then
# line 1012 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    literal.extend_space @ts, @te
   end
                end
        when 200 then
# line 1196 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tREGEXP_OPT, tok(@ts, @te - 1), @ts, @te - 1)
        p = p - 1;
                begin
                 @cs = 781
                _goto_level = _again
                next
        end

       end
                end
        when 201 then
# line 1183 "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 = 781;
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 16 then
# line 1335 "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 202 then
# line 1335 "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 204 then
# line 1348 "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 203 then
# line 1358 "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 225 then
# line 1379 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(KEYWORDS_BEGIN);
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 211 then
# line 1387 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tIDENTIFIER)
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 18 then
# line 1391 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1
            @cs = 781;  begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 328
                _goto_level = _again
                next
        end
  end
                end
        when 208 then
# line 1400 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 220 then
# line 1404 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1; p = p - 1;   begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 20 then
# line 1410 "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 = 781
                _goto_level = _again
                next
        end

        end
       end
                end
        when 207 then
# line 1423 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 206 then
# line 527 "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 224 then
# line 1379 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(KEYWORDS_BEGIN);
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 221 then
# line 1383 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tCONSTANT)
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 223 then
# line 1387 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tIDENTIFIER)
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 218 then
# line 1391 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
            @cs = 781;  begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 328
                _goto_level = _again
                next
        end
  end
                end
        when 214 then
# line 1400 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 219 then
# line 1407 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 212 then
# line 1420 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 217 then
# line 1423 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 19 then
# line 1400 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  emit_table(PUNCTUATION)
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 17 then
# line 1423 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 210 then
# line 1 "NONE"
                begin
        case  @act
        when 43 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS_BEGIN);
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 44 then
        begin begin p = (( @te))-1; end
 emit(:tCONSTANT)
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 45 then
        begin begin p = (( @te))-1; end
 emit(:tIDENTIFIER)
            @cs = 446;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
end 
                        end
        when 22 then
# line 1435 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1)
           p = p - 1;  @cs = 766;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 227 then
# line 1441 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 226 then
# line 527 "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 229 then
# line 1438 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 228 then
# line 1441 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 21 then
# line 1441 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 235 then
# line 1467 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 474;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 234 then
# line 1473 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 233 then
# line 527 "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 245 then
# line 1452 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tCONSTANT)
            @cs = (arg_or_cmdarg(cmd_state));   begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 236 then
# line 1456 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tIDENTIFIER)
            @cs = (arg_or_cmdarg(cmd_state));   begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 241 then
# line 1467 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 474;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 239 then
# line 1470 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 244 then
# line 1473 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 268 then
# line 1533 "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 = 781
                _goto_level = _again
                next
        end

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

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

       end
                end
        when 257 then
# line 1579 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1; p = p - 1;   begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 24 then
# line 1587 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1;    begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 259 then
# line 1596 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = tm - 1;     begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 39 then
# line 1607 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end

       end
                end
        when 246 then
# line 1621 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 247 then
# line 527 "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 258 then
# line 1542 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 254 then
# line 1568 "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 = 543
                _goto_level = _again
                next
        end

       end
                end
        when 256 then
# line 1584 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 250 then
# line 1607 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end

       end
                end
        when 249 then
# line 1612 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 267 then
# line 1621 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 25 then
# line 1612 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
                end
        when 41 then
# line 1621 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 23 then
# line 1 "NONE"
                begin
        case  @act
        when 71 then
        begin begin p = (( @te))-1; end

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

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

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

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

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

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

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

      end
        else
        begin begin p = (( @te))-1; end
end
end 
                        end
        when 43 then
# line 1657 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1
                begin
                 @cs = 474
                _goto_level = _again
                next
        end
  end
                end
        when 272 then
# line 527 "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 273 then
# line 1657 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 474
                _goto_level = _again
                next
        end
  end
                end
        when 44 then
# line 1657 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = @ts - 1
                begin
                 @cs = 474
                _goto_level = _again
                next
        end
  end
                end
        when 42 then
# line 1 "NONE"
                begin
        case  @act
        when 84 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 = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 85 then
        begin begin p = (( @te))-1; end
 p = @ts - 1
                begin
                 @cs = 474
                _goto_level = _again
                next
        end
 end
end 
                        end
        when 283 then
# line 1693 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_do(true)
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 276 then
# line 1699 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 277 then
# line 527 "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 278 then
# line 1696 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 281 then
# line 1699 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 287 then
# line 1723 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 286 then
# line 527 "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 295 then
# line 1715 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1;  begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 289 then
# line 1717 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 293 then
# line 1723 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 288 then
# line 1 "NONE"
                begin
        case  @act
        when 92 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 93 then
        begin begin p = (( @te))-1; end
 p = @ts - 1;   begin
                 @cs = 543
                _goto_level = _again
                next
        end
 end
end 
                        end
        when 56 then
# line 1738 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1)
        p = p - 1;  @cs = 781;  begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 328 then
# line 1755 "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 320 then
# line 1762 "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 54 then
# line 1769 "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 341 then
# line 1844 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = p - 1; p = p - 1;
        emit(:tSYMBEG, tok(@ts, @ts + 1), @ts, @ts + 1)
                begin
                 @cs = 333
                _goto_level = _again
                next
        end

       end
                end
        when 329 then
# line 1852 "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 340 then
# line 1860 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tSYMBOL, tok(@ts + 1, @ts + 2))
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

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

       end
                end
        when 351 then
# line 1915 "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 = 781
                _goto_level = _again
                next
        end

       end
                end
        when 350 then
# line 1925 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1)
       end
                end
        when 330 then
# line 1984 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION_BEGIN)
                begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 51 then
# line 2005 "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 = 781;
          else
             @cs = (arg_or_cmdarg(cmd_state));
          end
        else
          emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1)
           @cs = 766;
        end

                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 327 then
# line 2043 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        if @version >= 30
          if @lambda_stack.any? && @lambda_stack.last + 1 == @paren_nest
            # To reject `->(...)` like `->...`
            emit(:tDOT3)
          else
            emit(:tBDOT3)
          end
        elsif @version >= 27
          emit(:tBDOT3)
        else
          emit(:tDOT3)
        end

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

       end
                end
        when 48 then
# line 2079 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tIDENTIFIER, ident_tok, ident_ts, ident_te)
        p = ident_te - 1

        if !@static_env.nil? && @static_env.declared?(ident_tok) && @version < 25
           @cs = 446;
        else
           @cs = 505;
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 314 then
# line 2098 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = @ts - 1
        @cs_before_block_comment = @cs
                begin
                 @cs = 185
                _goto_level = _again
                next
        end

       end
                end
        when 55 then
# line 2114 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1;    begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 298 then
# line 527 "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 325 then
# line 1738 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1)
        p = p - 1;  @cs = 781;  begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 324 then
# line 1745 "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 321 then
# line 1769 "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 319 then
# line 1775 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1)
       end
                end
        when 348 then
# line 1835 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1)
       end
                end
        when 331 then
# line 1874 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1), @ts)
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 344 then
# line 1882 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @version >= 27
          diagnostic :error, diag_msg, { name: tok(tm, @te) }, range(tm, @te)
        else
          emit(:tCOLON, tok(@ts, @ts + 1), @ts, @ts + 1)
          p = @ts
        end

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

       end
                end
        when 349 then
# line 1925 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1)
       end
                end
        when 355 then
# line 1931 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end

       end
                end
        when 322 then
# line 1984 "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 326 then
# line 2032 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @version >= 27
          emit(:tBDOT2)
        else
          emit(:tDOT2)
        end

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

       end
                end
        when 301 then
# line 1320 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    emit(:tIDENTIFIER)

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

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

    end
   end
                end
        when 311 then
# line 2095 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 313 then
# line 2098 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        p = @ts - 1
        @cs_before_block_comment = @cs
                begin
                 @cs = 185
                _goto_level = _again
                next
        end

       end
                end
        when 316 then
# line 2114 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1;  begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 53 then
# line 1775 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1)
       end
                end
        when 72 then
# line 1835 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1)
       end
                end
        when 73 then
# line 1902 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 47 then
# line 1320 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
    emit(:tIDENTIFIER)

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

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

    end
   end
                end
        when 52 then
# line 2095 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
                end
        when 67 then
# line 2114 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = @ts - 1;    begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 50 then
# line 1 "NONE"
                begin
        case  @act
        when 98 then
        begin begin p = (( @te))-1; end

        emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1)
        p = p - 1;  @cs = 781;  begin
                p += 1
                _goto_level = _out
                next
        end

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

        diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1)
      end
        when 116 then
        begin begin p = (( @te))-1; end

        if @version >= 27
          emit(:tPIPE, tok(@ts, @ts + 1), @ts, @ts + 1)
          p = p - 1;
           @cs = 543;   begin
                p += 1
                _goto_level = _out
                next
        end

        else
          p -= 2
                begin
                 @cs = 781
                _goto_level = _again
                next
        end

        end
      end
        when 120 then
        begin begin p = (( @te))-1; end
 emit_table(PUNCTUATION_BEGIN)
                begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 121 then
        begin begin p = (( @te))-1; end
 emit(:kRESCUE, 'rescue'.freeze, @ts, tm)
           p = tm - 1
            @cs = 519;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 122 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS_BEGIN)
           @command_start = true
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 126 then
        begin begin p = (( @te))-1; end
 p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
 end
        when 127 then
        begin begin p = (( @te))-1; end

    emit(:tIDENTIFIER)

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

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

    end
  end
        when 131 then
        begin begin p = (( @te))-1; end
 p = @ts - 1;   begin
                 @cs = 781
                _goto_level = _again
                next
        end
 end
end 
                        end
        when 386 then
# line 2134 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 387 then
# line 527 "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 388 then
# line 2122 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 392 then
# line 2134 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 76 then
# line 2144 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 396 then
# line 2149 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
                begin
                 @cs = (push_literal(tok, tok, @ts))
                _goto_level = _again
                next
        end

       end
                end
        when 395 then
# line 2159 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = p - 1;      begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 394 then
# line 527 "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 398 then
# line 2153 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 397 then
# line 2159 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 75 then
# line 2159 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  p = p - 1;      begin
                 @cs = 543
                _goto_level = _again
                next
        end
  end
                end
        when 431 then
# line 2170 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tLAMBDA, '->'.freeze, @ts, @ts + 2)

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

       end
                end
        when 85 then
# line 2211 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:kCLASS, 'class'.freeze, @ts, @ts + 5)
           emit(:tLSHFT, '<<'.freeze,    @te - 2, @te)
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 406 then
# line 2347 "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 78 then
# line 2365 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = @ts - 1;    begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 328
                _goto_level = _again
                next
        end
  end
                end
        when 427 then
# line 2372 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 453;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 480 then
# line 2396 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit_table(PUNCTUATION)
         @cs = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 420 then
# line 2405 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit_table(PUNCTUATION);
         @cs = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 425 then
# line 2440 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tOP_ASGN, tok(@ts, @te - 1))
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 411 then
# line 2444 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tEH, '?'.freeze)
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 408 then
# line 2463 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit_table(PUNCTUATION)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 410 then
# line 2476 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tSEMI, ';'.freeze)
           @command_start = true
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 485 then
# line 2480 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        diagnostic :error, :bare_backslash, nil, range(@ts, @ts + 1)
        p = p - 1;
       end
                end
        when 405 then
# line 2486 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] }
       end
                end
        when 404 then
# line 527 "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 496 then
# line 2207 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(KEYWORDS)
            @cs = 333;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 494 then
# line 2211 "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 = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 493 then
# line 2222 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(KEYWORDS)
           @command_start = true
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 435 then
# line 2297 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :error, :no_dot_digit_literal
       end
                end
        when 482 then
# line 2357 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tCONSTANT)
            @cs = (arg_or_cmdarg(cmd_state));   begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 424 then
# line 2365 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1;  begin
                 @stack[ @top] =  @cs
                 @top+= 1
                 @cs = 328
                _goto_level = _again
                next
        end
  end
                end
        when 432 then
# line 2372 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 453;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 488 then
# line 1320 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
    emit(:tIDENTIFIER)

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

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

    end
   end
                end
        when 430 then
# line 2396 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit_table(PUNCTUATION)
         @cs = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 426 then
# line 2405 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit_table(PUNCTUATION);
         @cs = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 419 then
# line 2411 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 433 then
# line 2463 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 417 then
# line 2470 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 423 then
# line 2486 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] }
       end
                end
        when 83 then
# line 2270 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 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 79 then
# line 2297 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        diagnostic :error, :no_dot_digit_literal
       end
                end
        when 82 then
# line 2329 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 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 77 then
# line 2486 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] }
       end
                end
        when 80 then
# line 1 "NONE"
                begin
        case  @act
        when 144 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
        if tok == '{'.freeze
          @paren_nest += 1
        end
        @command_start = true

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

      end
        when 145 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 333;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 146 then
        begin begin p = (( @te))-1; end
 emit(:kCLASS, 'class'.freeze, @ts, @ts + 5)
           emit(:tLSHFT, '<<'.freeze,    @te - 2, @te)
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 147 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 148 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
           @command_start = true
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 149 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 519;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 150 then
        begin begin p = (( @te))-1; end

        emit_table(KEYWORDS)

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

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

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

        if version?(18)
          emit(:tIDENTIFIER)

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

      end
        when 152 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
                begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 153 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 155 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 156 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 157 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 159 then
        begin begin p = (( @te))-1; end
 emit(:tCONSTANT)
            @cs = (arg_or_cmdarg(cmd_state));   begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 163 then
        begin begin p = (( @te))-1; end

    emit(:tIDENTIFIER)

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

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

    end
  end
        when 164 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 = 474;     begin
                p += 1
                _goto_level = _out
                next
        end

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

        emit_table(PUNCTUATION);
         @cs = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 167 then
        begin begin p = (( @te))-1; end
 emit_table(PUNCTUATION)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
end 
                        end
        when 95 then
# line 2516 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = tm - 1;     begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 501 then
# line 2519 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  emit(:tNL, nil, @newline_s, @newline_s + 1)
           p = p - 1;  @cs = 185;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 504 then
# line 2502 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @version < 27
          # Ruby before 2.7 doesn't support comments before leading dot.
          # If a line after "a" starts with a comment then "a" is a self-contained statement.
          # So in that case we emit a special tNL token and start reading the
          # next line as a separate statement.
          #
          # Note: block comments before leading dot are not supported on any version of Ruby.
          emit(:tNL, nil, @newline_s, @newline_s + 1)
          p = p - 1;  @cs = 185;        begin
                p += 1
                _goto_level = _out
                next
        end

        end
       end
                end
        when 503 then
# line 2519 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tNL, nil, @newline_s, @newline_s + 1)
           p = p - 1;  @cs = 185;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 90 then
# line 2502 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin 
        if @version < 27
          # Ruby before 2.7 doesn't support comments before leading dot.
          # If a line after "a" starts with a comment then "a" is a self-contained statement.
          # So in that case we emit a special tNL token and start reading the
          # next line as a separate statement.
          #
          # Note: block comments before leading dot are not supported on any version of Ruby.
          emit(:tNL, nil, @newline_s, @newline_s + 1)
          p = p - 1;  @cs = 185;        begin
                p += 1
                _goto_level = _out
                next
        end

        end
       end
                end
        when 86 then
# line 2519 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  emit(:tNL, nil, @newline_s, @newline_s + 1)
           p = p - 1;  @cs = 185;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 91 then
# line 1 "NONE"
                begin
        case  @act
        when 180 then
        begin begin p = (( @te))-1; end

        if @version < 27
          # Ruby before 2.7 doesn't support comments before leading dot.
          # If a line after "a" starts with a comment then "a" is a self-contained statement.
          # So in that case we emit a special tNL token and start reading the
          # next line as a separate statement.
          #
          # Note: block comments before leading dot are not supported on any version of Ruby.
          emit(:tNL, nil, @newline_s, @newline_s + 1)
          p = p - 1;  @cs = 185;        begin
                p += 1
                _goto_level = _out
                next
        end

        end
      end
        when 182 then
        begin begin p = (( @te))-1; end
 emit(:tNL, nil, @newline_s, @newline_s + 1)
           p = p - 1;  @cs = 185;       begin
                p += 1
                _goto_level = _out
                next
        end
 end
end 
                        end
        when 507 then
# line 2529 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit_comment(@eq_begin_s, @te)
                begin
                 @cs = (@cs_before_block_comment)
                _goto_level = _again
                next
        end

       end
                end
        when 506 then
# line 2537 "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 106 then
# line 2547 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  @eq_begin_s = @ts
                begin
                 @cs = 967
                _goto_level = _again
                next
        end
  end
                end
        when 2 then
# line 2551 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = pe - 3  end
                end
        when 98 then
# line 2554 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  cmd_state = true; p = p - 1;    begin
                 @cs = 773
                _goto_level = _again
                next
        end
  end
                end
        when 99 then
# line 527 "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 100 then
# line 2544 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 105 then
# line 2547 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  @eq_begin_s = @ts
                begin
                 @cs = 967
                _goto_level = _again
                next
        end
  end
                end
        when 104 then
# line 2554 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  cmd_state = true; p = p - 1;  begin
                 @cs = 773
                _goto_level = _again
                next
        end
  end
                end
        when 1 then
# line 2554 "lib/parser/lexer.rl"
                begin
 begin p = (( @te))-1; end
 begin  cmd_state = true; p = p - 1;    begin
                 @cs = 773
                _goto_level = _again
                next
        end
  end
                end
        when 66 then
# line 501 "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 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
        when 110 then
# line 501 "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 950 "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 140 then
# line 501 "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 950 "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 168 then
# line 501 "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 950 "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 174 then
# line 501 "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 950 "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 180 then
# line 501 "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 950 "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 187 then
# line 501 "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 950 "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 190 then
# line 501 "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 950 "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 198 then
# line 501 "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 950 "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 269 then
# line 501 "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 1533 "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 = 781
                _goto_level = _again
                next
        end

       end
                end
        when 260 then
# line 501 "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 1596 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = tm - 1;     begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 252 then
# line 501 "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 1607 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end

       end
                end
        when 352 then
# line 501 "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 1915 "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 = 781
                _goto_level = _again
                next
        end

       end
                end
        when 315 then
# line 501 "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 2098 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = @ts - 1
        @cs_before_block_comment = @cs
                begin
                 @cs = 185
                _goto_level = _again
                next
        end

       end
                end
        when 434 then
# line 501 "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 2452 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        if @paren_nest == 0
          diagnostic :warning, :triple_dot_at_eol, nil, range(@ts, @te - 1)
        end

        emit(:tDOT3, '...'.freeze, @ts, @te - 1)
        p = p - 1;
         @cs = 543;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 508 then
# line 501 "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 2529 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit_comment(@eq_begin_s, @te)
                begin
                 @cs = (@cs_before_block_comment)
                _goto_level = _again
                next
        end

       end
                end
        when 505 then
# line 501 "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 2534 "lib/parser/lexer.rl"
                begin
 @te = p+1
                end
        when 107 then
# line 501 "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 2547 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  @eq_begin_s = @ts
                begin
                 @cs = 967
                _goto_level = _again
                next
        end
  end
                end
        when 3 then
# line 501 "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 2551 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = pe - 3  end
                end
        when 456 then
# line 635 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tRATIONAL,  Rational(chars)) }              end
# line 2270 "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 454 then
# line 636 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, chars)) }            end
# line 2270 "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 459 then
# line 637 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Rational(chars))) }          end
# line 2270 "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 457 then
# line 638 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars, @ts, @te - 2); p -= 2 }          end
# line 2270 "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 455 then
# line 639 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars, @ts, @te - 2); p -= 2 }          end
# line 2270 "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 458 then
# line 640 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars, @ts, @te - 6); p -= 6 }          end
# line 2270 "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 447 then
# line 644 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Float(chars))) }             end
# line 2329 "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 448 then
# line 645 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tFLOAT,     Float(chars), @ts, @te - 2); p -= 2 }           end
# line 2329 "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 449 then
# line 649 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tRATIONAL,  Rational(chars)) }              end
# line 2329 "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 451 then
# line 650 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Rational(chars))) }          end
# line 2329 "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 450 then
# line 651 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tFLOAT,     Float(chars), @ts, @te - 6); p -= 6 }           end
# line 2329 "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 134 then
# line 666 "lib/parser/lexer.rl"
                begin

    @escape = ""

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

    if @version < 24
      if codepoints.start_with?(" ") || codepoints.start_with?("\t")
        diagnostic :fatal, :invalid_unicode_escape, nil,
          range(@escape_s + 2, @escape_s + 3)
      end

      if spaces_p = codepoints.index(/[ \t]{2}/)
        diagnostic :fatal, :invalid_unicode_escape, nil,
          range(codepoint_s + spaces_p + 1, codepoint_s + spaces_p + 2)
      end

      if codepoints.end_with?(" ") || codepoints.end_with?("\t")
        diagnostic :fatal, :invalid_unicode_escape, nil, range(p - 1, p)
      end
    end

    codepoints.scan(/([0-9a-fA-F]+)|([ \t]+)/).each do |(codepoint_str, spaces)|
      if spaces
        codepoint_s += spaces.length
      else
        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
      end
    end
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 162 then
# line 666 "lib/parser/lexer.rl"
                begin

    @escape = ""

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

    if @version < 24
      if codepoints.start_with?(" ") || codepoints.start_with?("\t")
        diagnostic :fatal, :invalid_unicode_escape, nil,
          range(@escape_s + 2, @escape_s + 3)
      end

      if spaces_p = codepoints.index(/[ \t]{2}/)
        diagnostic :fatal, :invalid_unicode_escape, nil,
          range(codepoint_s + spaces_p + 1, codepoint_s + spaces_p + 2)
      end

      if codepoints.end_with?(" ") || codepoints.end_with?("\t")
        diagnostic :fatal, :invalid_unicode_escape, nil, range(p - 1, p)
      end
    end

    codepoints.scan(/([0-9a-fA-F]+)|([ \t]+)/).each do |(codepoint_str, spaces)|
      if spaces
        codepoint_s += spaces.length
      else
        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
      end
    end
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 373 then
# line 666 "lib/parser/lexer.rl"
                begin

    @escape = ""

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

    if @version < 24
      if codepoints.start_with?(" ") || codepoints.start_with?("\t")
        diagnostic :fatal, :invalid_unicode_escape, nil,
          range(@escape_s + 2, @escape_s + 3)
      end

      if spaces_p = codepoints.index(/[ \t]{2}/)
        diagnostic :fatal, :invalid_unicode_escape, nil,
          range(codepoint_s + spaces_p + 1, codepoint_s + spaces_p + 2)
      end

      if codepoints.end_with?(" ") || codepoints.end_with?("\t")
        diagnostic :fatal, :invalid_unicode_escape, nil, range(p - 1, p)
      end
    end

    codepoints.scan(/([0-9a-fA-F]+)|([ \t]+)/).each do |(codepoint_str, spaces)|
      if spaces
        codepoint_s += spaces.length
      else
        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
      end
    end
                end
# line 1902 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 118 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 146 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

    if (@escape = ESCAPES[codepoint]).nil?
      @escape = encode_escape(@source_buffer.slice(p - 1))
    end
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 357 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 121 then
# line 718 "lib/parser/lexer.rl"
                begin

    diagnostic :fatal, :invalid_escape
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 149 then
# line 718 "lib/parser/lexer.rl"
                begin

    diagnostic :fatal, :invalid_escape
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 360 then
# line 718 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 123 then
# line 745 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 151 then
# line 745 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 362 then
# line 745 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 1902 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 120 then
# line 752 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100)             end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 148 then
# line 752 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100)             end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 359 then
# line 752 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100)             end
# line 1902 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 137 then
# line 756 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s + 1, p).to_i(16))                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 165 then
# line 756 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s + 1, p).to_i(16))                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 376 then
# line 756 "lib/parser/lexer.rl"
                begin
 @escape = encode_escape(tok(@escape_s + 1, p).to_i(16))                end
# line 1902 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

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

        diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 164 then
# line 760 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 375 then
# line 760 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 131 then
# line 766 "lib/parser/lexer.rl"
                begin
 @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8)          end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 159 then
# line 766 "lib/parser/lexer.rl"
                begin
 @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8)          end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 370 then
# line 766 "lib/parser/lexer.rl"
                begin
 @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8)          end
# line 1902 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 130 then
# line 770 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 158 then
# line 770 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 369 then
# line 770 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 135 then
# line 776 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 163 then
# line 776 "lib/parser/lexer.rl"
                begin

        diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 374 then
# line 776 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 132 then
# line 790 "lib/parser/lexer.rl"
                begin

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 160 then
# line 790 "lib/parser/lexer.rl"
                begin

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 371 then
# line 790 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 119 then
# line 816 "lib/parser/lexer.rl"
                begin

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 147 then
# line 816 "lib/parser/lexer.rl"
                begin

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 358 then
# line 816 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 171 then
# line 822 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 176 then
# line 822 "lib/parser/lexer.rl"
                begin

    @escape_s = p
    @escape   = nil
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 57 then
# line 862 "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 501 "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 30 then
# line 862 "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 1547 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 32 then
# line 862 "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 1567 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 34 then
# line 862 "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 1595 "lib/parser/lexer.rl"
                begin
 tm = p                 end
        when 213 then
# line 862 "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 1420 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 232 then
# line 862 "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 1438 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 240 then
# line 862 "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 1470 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 33 then
# line 862 "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 1607 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end

       end
                end
        when 271 then
# line 862 "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 1612 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 263 then
# line 862 "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 1618 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 282 then
# line 862 "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 1696 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 294 then
# line 862 "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 1717 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 290 then
# line 862 "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 1720 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = p - 1;    begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 58 then
# line 862 "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 1738 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1)
        p = p - 1;  @cs = 781;  begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 49 then
# line 862 "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 2079 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin 
        emit(:tIDENTIFIER, ident_tok, ident_ts, ident_te)
        p = ident_te - 1

        if !@static_env.nil? && @static_env.declared?(ident_tok) && @version < 25
           @cs = 446;
        else
           @cs = 505;
        end
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 312 then
# line 862 "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 2095 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 393 then
# line 862 "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 2122 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 389 then
# line 862 "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 2125 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
      if @in_kwarg
        p = p - 1;      begin
                 @cs = 781
                _goto_level = _again
                next
        end

      else
                begin
                 @cs = 185
                _goto_level = _again
                next
        end

      end
     end
                end
        when 402 then
# line 862 "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 2153 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 399 then
# line 862 "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 2156 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin        begin
                 @cs = 185
                _goto_level = _again
                next
        end
  end
                end
        when 486 then
# line 862 "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 2470 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 418 then
# line 862 "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 2473 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin        begin
                 @cs = 961
                _goto_level = _again
                next
        end
  end
                end
        when 101 then
# line 862 "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 2544 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 262 then
# line 1064 "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 1514 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @lambda_stack.last == @paren_nest
          @lambda_stack.pop
          emit(:tLAMBEG, '{'.freeze, @te - 1, @te)
        else
          emit(:tLCURLY, '{'.freeze, @te - 1, @te)
        end
        @command_start = true
        @paren_nest += 1
         @cs = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 284 then
# line 1064 "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 1680 "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_ARG, '{'.freeze)
        end
        @paren_nest += 1
        @command_start = true
         @cs = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 384 then
# line 1064 "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 1960 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @lambda_stack.last == @paren_nest
          @lambda_stack.pop
          @command_start = true
          emit(:tLAMBEG, '{'.freeze)
        else
          emit(:tLBRACE, '{'.freeze)
        end
        @paren_nest += 1
                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 499 then
# line 1064 "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 2178 "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
        if tok == '{'.freeze
          @paren_nest += 1
        end
        @command_start = true

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

       end
                end
        when 500 then
# line 1073 "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)
          @cond.lexpop
          @cmdarg.lexpop
        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 = (next_state_for_literal(current_literal));
                begin
                p += 1
                _goto_level = _out
                next
        end

      end
    end

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

        if @version < 24
          @cond.lexpop
          @cmdarg.lexpop
        else
          @cond.pop
          @cmdarg.pop
        end

        if tok == '}'.freeze || tok == ']'.freeze
          if @version >= 25
             @cs = 781;
          else
             @cs = 511;
          end
        else # )
          # fnext expr_endfn; ?
        end

                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 60 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
        when 64 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 501 "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 216 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1420 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 231 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1438 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 243 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1470 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 265 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1615 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin        begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 280 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1696 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 292 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1717 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 318 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2095 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 391 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2122 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 401 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2153 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 422 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2470 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 103 then
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2544 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 237 then
# line 1266 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1460 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tFID, tok(@ts, tm), @ts, tm)
            @cs = (arg_or_cmdarg(cmd_state)); p = tm - 1;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 332 then
# line 1266 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1866 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 303 then
# line 1266 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 2068 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 415 then
# line 1266 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1 "NONE"
                begin
        case  @act
        when 144 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
        if tok == '{'.freeze
          @paren_nest += 1
        end
        @command_start = true

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

      end
        when 145 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 333;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 146 then
        begin begin p = (( @te))-1; end
 emit(:kCLASS, 'class'.freeze, @ts, @ts + 5)
           emit(:tLSHFT, '<<'.freeze,    @te - 2, @te)
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 147 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 148 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
           @command_start = true
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 149 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
            @cs = 519;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 150 then
        begin begin p = (( @te))-1; end

        emit_table(KEYWORDS)

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

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

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

        if version?(18)
          emit(:tIDENTIFIER)

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

      end
        when 152 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS)
                begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 153 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 155 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 156 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 157 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 159 then
        begin begin p = (( @te))-1; end
 emit(:tCONSTANT)
            @cs = (arg_or_cmdarg(cmd_state));   begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 163 then
        begin begin p = (( @te))-1; end

    emit(:tIDENTIFIER)

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

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

    end
  end
        when 164 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 = 474;     begin
                p += 1
                _goto_level = _out
                next
        end

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

        emit_table(PUNCTUATION);
         @cs = 773;     begin
                p += 1
                _goto_level = _out
                next
        end

      end
        when 167 then
        begin begin p = (( @te))-1; end
 emit_table(PUNCTUATION)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
end 
                        end
        when 238 then
# line 1267 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1460 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tFID, tok(@ts, tm), @ts, tm)
            @cs = (arg_or_cmdarg(cmd_state)); p = tm - 1;       begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 333 then
# line 1267 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1866 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 305 then
# line 1267 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 2068 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 416 then
# line 1267 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 2379 "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 = 474;     begin
                p += 1
                _goto_level = _out
                next
        end

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

       end
                end
        when 306 then
# line 1272 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 2068 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 335 then
# line 1273 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1866 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 307 then
# line 1273 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 2068 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 339 then
# line 1274 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1866 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 310 then
# line 1274 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 2068 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 338 then
# line 1275 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1866 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 309 then
# line 1275 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1 "NONE"
                begin
        case  @act
        when 98 then
        begin begin p = (( @te))-1; end

        emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1)
        p = p - 1;  @cs = 781;  begin
                p += 1
                _goto_level = _out
                next
        end

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

        diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1)
      end
        when 116 then
        begin begin p = (( @te))-1; end

        if @version >= 27
          emit(:tPIPE, tok(@ts, @ts + 1), @ts, @ts + 1)
          p = p - 1;
           @cs = 543;   begin
                p += 1
                _goto_level = _out
                next
        end

        else
          p -= 2
                begin
                 @cs = 781
                _goto_level = _again
                next
        end

        end
      end
        when 120 then
        begin begin p = (( @te))-1; end
 emit_table(PUNCTUATION_BEGIN)
                begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 121 then
        begin begin p = (( @te))-1; end
 emit(:kRESCUE, 'rescue'.freeze, @ts, tm)
           p = tm - 1
            @cs = 519;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 122 then
        begin begin p = (( @te))-1; end
 emit_table(KEYWORDS_BEGIN)
           @command_start = true
            @cs = 773;  begin
                p += 1
                _goto_level = _out
                next
        end
 end
        when 126 then
        begin begin p = (( @te))-1; end
 p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
 end
        when 127 then
        begin begin p = (( @te))-1; end

    emit(:tIDENTIFIER)

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

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

    end
  end
        when 131 then
        begin begin p = (( @te))-1; end
 p = @ts - 1;   begin
                 @cs = 781
                _goto_level = _again
                next
        end
 end
end 
                        end
        when 336 then
# line 1276 "lib/parser/lexer.rl"
                begin
 tm = p - 3             end
# line 1866 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 308 then
# line 1276 "lib/parser/lexer.rl"
                begin
 tm = p - 3             end
# line 2068 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  p = @ts - 1
                begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 337 then
# line 1281 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 1866 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm)
        p = tm - 1
         @cs = 781;     begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 481 then
# line 1286 "lib/parser/lexer.rl"
                begin
 tm = p - 2             end
# line 2361 "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 261 then
# line 1292 "lib/parser/lexer.rl"
                begin

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

    @paren_nest += 1
                end
# line 1508 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLBRACK, '['.freeze, @te - 1, @te)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 377 then
# line 1292 "lib/parser/lexer.rl"
                begin

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

    @paren_nest += 1
                end
# line 1974 "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 484 then
# line 1292 "lib/parser/lexer.rl"
                begin

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

    @paren_nest += 1
                end
# line 2448 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLBRACK2, '['.freeze)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 487 then
# line 1298 "lib/parser/lexer.rl"
                begin

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

        if @version < 24
          @cond.lexpop
          @cmdarg.lexpop
        else
          @cond.pop
          @cmdarg.pop
        end

        if tok == '}'.freeze || tok == ']'.freeze
          if @version >= 25
             @cs = 781;
          else
             @cs = 511;
          end
        else # )
          # fnext expr_endfn; ?
        end

                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 253 then
# line 1305 "lib/parser/lexer.rl"
                begin

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

    @paren_nest += 1

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

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

        end
       end
                end
        when 266 then
# line 1305 "lib/parser/lexer.rl"
                begin

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

    @paren_nest += 1

    if version?(18)
      @command_start = true
    end
                end
# line 1502 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:tLPAREN2, '('.freeze)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 274 then
# line 1305 "lib/parser/lexer.rl"
                begin

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

    @paren_nest += 1

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

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

        end
       end
                end
        when 323 then
# line 1305 "lib/parser/lexer.rl"
                begin

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

    @paren_nest += 1

    if version?(18)
      @command_start = true
    end
                end
# line 1979 "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 428 then
# line 1305 "lib/parser/lexer.rl"
                begin

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

    @paren_nest += 1

    if version?(18)
      @command_start = true
    end
                end
# line 2411 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit_table(PUNCTUATION)
            @cs = 543;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 429 then
# line 1315 "lib/parser/lexer.rl"
                begin

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

        if @version < 24
          @cond.lexpop
          @cmdarg.lexpop
        else
          @cond.pop
          @cmdarg.pop
        end

        if tok == '}'.freeze || tok == ']'.freeze
          if @version >= 25
             @cs = 781;
          else
             @cs = 511;
          end
        else # )
          # fnext expr_endfn; ?
        end

                begin
                p += 1
                _goto_level = _out
                next
        end

       end
                end
        when 71 then
# line 1787 "lib/parser/lexer.rl"
                begin
 heredoc_e      = p             end
# line 501 "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 347 then
# line 1788 "lib/parser/lexer.rl"
                begin
 new_herebody_s = p             end
# line 1789 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        tok(@ts, heredoc_e) =~ /^<<(-?)(~?)(["'`]?)(.*)\3$/m

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

        if @version >= 27
          if delimiter.count("\n") > 0 || delimiter.count("\r") > 0
            diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1)
          end
        elsif @version >= 24
          if delimiter.count("\n") > 0
            if delimiter.end_with?("\n")
              diagnostic :warning, :heredoc_id_ends_with_nl, nil, range(@ts, @ts + 1)
              delimiter = delimiter.rstrip
            else
              diagnostic :fatal, :heredoc_id_has_newline, nil, range(@ts, @ts + 1)
            end
          end
        end

        if dedent_body && version?(18, 19, 20, 21, 22)
          emit(:tLSHFT, '<<'.freeze, @ts, @ts + 2)
          p = @ts + 1
           @cs = 543;   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 342 then
# line 1879 "lib/parser/lexer.rl"
                begin
 tm = p - 1; diag_msg = :ivar_name              end
# line 1882 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @version >= 27
          diagnostic :error, diag_msg, { name: tok(tm, @te) }, range(tm, @te)
        else
          emit(:tCOLON, tok(@ts, @ts + 1), @ts, @ts + 1)
          p = @ts
        end

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

       end
                end
        when 345 then
# line 1880 "lib/parser/lexer.rl"
                begin
 tm = p - 2; diag_msg = :cvar_name              end
# line 1882 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        if @version >= 27
          diagnostic :error, diag_msg, { name: tok(tm, @te) }, range(tm, @te)
        else
          emit(:tCOLON, tok(@ts, @ts + 1), @ts, @ts + 1)
          p = @ts
        end

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

       end
                end
        when 353 then
# line 1900 "lib/parser/lexer.rl"
                begin
 @escape = nil          end
# line 1902 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin 
        value = @escape || tok(@ts + 1)

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 380 then
# line 1989 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1990 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin  emit(:kRESCUE, 'rescue'.freeze, @ts, tm)
           p = tm - 1
            @cs = 519;  begin
                p += 1
                _goto_level = _out
                next
        end
  end
                end
        when 471 then
# line 2263 "lib/parser/lexer.rl"
                begin
 @num_base = 16; @num_digits_s = p              end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 465 then
# line 2264 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = p              end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 468 then
# line 2265 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = p              end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 462 then
# line 2266 "lib/parser/lexer.rl"
                begin
 @num_base = 2;  @num_digits_s = p              end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 477 then
# line 2267 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 440 then
# line 2268 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 478 then
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
        when 89 then
# line 2515 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 2516 "lib/parser/lexer.rl"
                begin
 @te = p+1
 begin  p = tm - 1;     begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 8 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 501 "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 444 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2327 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
        when 222 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1379 "lib/parser/lexer.rl"
                begin
 @act = 43;             end
        when 209 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1383 "lib/parser/lexer.rl"
                begin
 @act = 44;             end
        when 205 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1387 "lib/parser/lexer.rl"
                begin
 @act = 45;             end
        when 26 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1551 "lib/parser/lexer.rl"
                begin
 @act = 71;             end
        when 255 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1568 "lib/parser/lexer.rl"
                begin
 @act = 72;             end
        when 27 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1607 "lib/parser/lexer.rl"
                begin
 @act = 77;             end
        when 248 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1612 "lib/parser/lexer.rl"
                begin
 @act = 78;             end
        when 275 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1644 "lib/parser/lexer.rl"
                begin
 @act = 84;             end
        when 45 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1657 "lib/parser/lexer.rl"
                begin
 @act = 85;             end
        when 296 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1711 "lib/parser/lexer.rl"
                begin
 @act = 92;             end
        when 285 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1715 "lib/parser/lexer.rl"
                begin
 @act = 93;             end
        when 69 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1835 "lib/parser/lexer.rl"
                begin
 @act = 105;            end
        when 385 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1943 "lib/parser/lexer.rl"
                begin
 @act = 116;            end
        when 299 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1984 "lib/parser/lexer.rl"
                begin
 @act = 120;            end
        when 379 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1990 "lib/parser/lexer.rl"
                begin
 @act = 121;            end
        when 378 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1996 "lib/parser/lexer.rl"
                begin
 @act = 122;            end
        when 74 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2068 "lib/parser/lexer.rl"
                begin
 @act = 126;            end
        when 297 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1320 "lib/parser/lexer.rl"
                begin
 @act = 127;            end
        when 300 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2114 "lib/parser/lexer.rl"
                begin
 @act = 131;            end
        when 495 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2178 "lib/parser/lexer.rl"
                begin
 @act = 144;            end
        when 490 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2207 "lib/parser/lexer.rl"
                begin
 @act = 145;            end
        when 498 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2217 "lib/parser/lexer.rl"
                begin
 @act = 147;            end
        when 491 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2222 "lib/parser/lexer.rl"
                begin
 @act = 148;            end
        when 492 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2227 "lib/parser/lexer.rl"
                begin
 @act = 149;            end
        when 497 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2231 "lib/parser/lexer.rl"
                begin
 @act = 150;            end
        when 489 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2242 "lib/parser/lexer.rl"
                begin
 @act = 151;            end
        when 483 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2256 "lib/parser/lexer.rl"
                begin
 @act = 152;            end
        when 409 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2270 "lib/parser/lexer.rl"
                begin
 @act = 153;            end
        when 442 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2314 "lib/parser/lexer.rl"
                begin
 @act = 156;            end
        when 81 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2329 "lib/parser/lexer.rl"
                begin
 @act = 157;            end
        when 412 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2357 "lib/parser/lexer.rl"
                begin
 @act = 159;            end
        when 403 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1320 "lib/parser/lexer.rl"
                begin
 @act = 163;            end
        when 414 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2379 "lib/parser/lexer.rl"
                begin
 @act = 164;            end
        when 407 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2405 "lib/parser/lexer.rl"
                begin
 @act = 166;            end
        when 413 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2411 "lib/parser/lexer.rl"
                begin
 @act = 167;            end
        when 87 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2502 "lib/parser/lexer.rl"
                begin
 @act = 180;            end
        when 502 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2519 "lib/parser/lexer.rl"
                begin
 @act = 182;            end
        when 177 then
# line 501 "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 950 "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 822 "lib/parser/lexer.rl"
                begin

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

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 152 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 363 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 129 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 157 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 368 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 122 then
# line 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 730 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 150 then
# line 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 730 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord & 0x9f)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 361 then
# line 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 730 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 128 then
# line 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 734 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 156 then
# line 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 734 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 367 then
# line 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 734 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 126 then
# line 745 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 734 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 154 then
# line 745 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 734 "lib/parser/lexer.rl"
                begin

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 365 then
# line 745 "lib/parser/lexer.rl"
                begin
 @escape = "\x7f"               end
# line 734 "lib/parser/lexer.rl"
                begin

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 133 then
# line 776 "lib/parser/lexer.rl"
                begin

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

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 161 then
# line 776 "lib/parser/lexer.rl"
                begin

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

          diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p)
                        end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 372 then
# line 776 "lib/parser/lexer.rl"
                begin

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

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 116 then
# line 822 "lib/parser/lexer.rl"
                begin

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

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 145 then
# line 822 "lib/parser/lexer.rl"
                begin

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

      diagnostic :fatal, :escape_eof, nil, range(p - 1, p)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 356 then
# line 822 "lib/parser/lexer.rl"
                begin

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

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 61 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 501 "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 215 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1420 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 230 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1438 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 242 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1470 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 264 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1615 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1; begin        begin
                 @cs = 781
                _goto_level = _again
                next
        end
  end
                end
        when 279 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1696 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 291 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1717 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 317 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2095 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 390 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2122 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 400 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2153 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 421 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2470 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 102 then
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2544 "lib/parser/lexer.rl"
                begin
 @te = p
p = p - 1;              end
        when 473 then
# line 2267 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
        when 437 then
# line 2268 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
        when 452 then
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2270 "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 445 then
# line 2326 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 643 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tFLOAT,     Float(chars)) }                 end
# line 2329 "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 441 then
# line 2327 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 643 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tFLOAT,     Float(chars)) }                 end
# line 2329 "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 270 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 501 "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 1612 "lib/parser/lexer.rl"
                begin
 @act = 78;             end
        when 35 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 862 "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 1607 "lib/parser/lexer.rl"
                begin
 @act = 77;             end
        when 46 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 862 "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 1657 "lib/parser/lexer.rl"
                begin
 @act = 85;             end
        when 94 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 862 "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 2502 "lib/parser/lexer.rl"
                begin
 @act = 180;            end
        when 65 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1738 "lib/parser/lexer.rl"
                begin
 @act = 98;             end
        when 84 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2211 "lib/parser/lexer.rl"
                begin
 @act = 146;            end
        when 93 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2502 "lib/parser/lexer.rl"
                begin
 @act = 180;            end
        when 37 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1567 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1568 "lib/parser/lexer.rl"
                begin
 @act = 72;             end
        when 382 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1989 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 2068 "lib/parser/lexer.rl"
                begin
 @act = 126;            end
        when 381 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1989 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1320 "lib/parser/lexer.rl"
                begin
 @act = 127;            end
        when 474 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2267 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2270 "lib/parser/lexer.rl"
                begin
 @act = 153;            end
        when 127 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

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

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 155 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

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

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 366 then
# line 706 "lib/parser/lexer.rl"
                begin

    codepoint = @source_pts[p - 1]

    if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
      diagnostic :fatal, :invalid_escape
    end

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

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

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 125 then
# line 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 730 "lib/parser/lexer.rl"
                begin

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

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 730 "lib/parser/lexer.rl"
                begin

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

    @escape = encode_escape(@escape[0].ord | 0x80)
                end
# line 895 "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.squiggly_heredoc? && escaped_char == "\n".freeze
        # Squiggly heredocs like
        #   <<~-HERE
        #     1\
        #     2
        #   HERE
        # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n".
        # This information is emitted as is, without escaping,
        # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter
        current_literal.extend_string(tok, @ts, @te)
      elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze
        # Heredocs, regexp and a few other types of literals support line
        # continuation via \\\n sequence. The code like
        #   "a\
        #   b"
        # must be parsed as "ab"
        current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
      elsif current_literal.regexp?
        # Regular expressions should include escape sequences in their
        # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
        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 364 then
# line 722 "lib/parser/lexer.rl"
                begin

    @escape = @source_buffer.slice(p - 1).chr

    if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
      diagnostic :fatal, :invalid_escape
    end
                end
# line 730 "lib/parser/lexer.rl"
                begin

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

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

        if version?(18)
          emit(:tINTEGER, value.getbyte(0))
        else
          emit(:tCHARACTER, value)
        end

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

       end
                end
        when 469 then
# line 2263 "lib/parser/lexer.rl"
                begin
 @num_base = 16; @num_digits_s = p              end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2270 "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 463 then
# line 2264 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = p              end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2270 "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 466 then
# line 2265 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = p              end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2270 "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 460 then
# line 2266 "lib/parser/lexer.rl"
                begin
 @num_base = 2;  @num_digits_s = p              end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2270 "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 472 then
# line 2267 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2270 "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 436 then
# line 2268 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2270 "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 31 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 862 "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 1567 "lib/parser/lexer.rl"
                begin
 tm = p                 end
# line 1568 "lib/parser/lexer.rl"
                begin
 @act = 72;             end
        when 62 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 1738 "lib/parser/lexer.rl"
                begin
 @act = 98;             end
        when 92 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 1222 "lib/parser/lexer.rl"
                begin
 @sharp_s = p - 1               end
# line 1225 "lib/parser/lexer.rl"
                begin
 emit_comment(@sharp_s, p == pe ? p - 2 : p)            end
# line 2502 "lib/parser/lexer.rl"
                begin
 @act = 180;            end
        when 479 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2302 "lib/parser/lexer.rl"
                begin
 @act = 155;            end
        when 475 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2267 "lib/parser/lexer.rl"
                begin
 @num_base = 10; @num_digits_s = @ts            end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2302 "lib/parser/lexer.rl"
                begin
 @act = 155;            end
        when 439 then
# line 1 "NONE"
                begin
 @te = p+1
                end
# line 2268 "lib/parser/lexer.rl"
                begin
 @num_base = 8;  @num_digits_s = @ts            end
# line 2269 "lib/parser/lexer.rl"
                begin
 @num_suffix_s = p              end
# line 634 "lib/parser/lexer.rl"
                begin
 @num_xfrm = lambda { |chars| emit(:tINTEGER,   chars) }                end
# line 2302 "lib/parser/lexer.rl"
                begin
 @act = 155;            end
# line 23594 "lib/parser/lexer.rb"
        end
        end
        end
        if _goto_level <= _again
        case _lex_to_state_actions[ @cs] 
        when 96 then
# line 1 "NONE"
                begin
 @ts = nil;             end
# line 23604 "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 286 "lib/parser/lexer.rl"
    # %

    # Ragel creates a local variable called `testEof` but it doesn't use
    # it in any assignment. This dead code is here to swallow the warning.
    # It has no runtime cost because Ruby doesn't produce any instructions from it.
    if false
      testEof
    end

    @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 10958
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 10908
def encoding
  @source_buffer.source.encoding
end
pop_cmdarg() click to toggle source
# File lib/parser/lexer.rb, line 10945
def pop_cmdarg
  @cmdarg = @cmdarg_stack.pop
end
pop_cond() click to toggle source
# File lib/parser/lexer.rb, line 10954
def pop_cond
  @cond = @cond_stack.pop
end
push_cmdarg() click to toggle source
# File lib/parser/lexer.rb, line 10940
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 10949
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 10819
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_start = true

  # True at the end of "def foo a:"
  @in_kwarg      = false

  # State before =begin / =end block comment
  @cs_before_block_comment = self.class.lex_en_line_begin
end
source_buffer=(source_buffer) click to toggle source
# File lib/parser/lexer.rb, line 10887
def source_buffer=(source_buffer)
  @source_buffer = source_buffer

  if @source_buffer
    source = @source_buffer.source

    if 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 10932
def state
  LEX_STATES.invert.fetch(@cs, @cs)
end
state=(state) click to toggle source
# File lib/parser/lexer.rb, line 10936
def state=(state)
  @cs = LEX_STATES.fetch(state)
end

Protected Instance Methods

arg_or_cmdarg(cmd_state) click to toggle source
# File lib/parser/lexer.rb, line 23707
def arg_or_cmdarg(cmd_state)
  if cmd_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 23727
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 23681
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 23715
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 23697
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 23691
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 23669
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 23656
def eof_codepoint?(point)
  [0x04, 0x1a, 0x00].include? point
end
literal() click to toggle source
# File lib/parser/lexer.rb, line 23770
def literal
  @literal_stack.last
end
next_state_for_literal(literal) click to toggle source
# File lib/parser/lexer.rb, line 23742
def next_state_for_literal(literal)
  if literal.words? && literal.backslash_delimited?
    if literal.interpolate?
      self.class.lex_en_interp_backslash_delimited_words
    else
      self.class.lex_en_plain_backslash_delimited_words
    end
  elsif literal.words? && !literal.backslash_delimited?
    if literal.interpolate?
      self.class.lex_en_interp_words
    else
      self.class.lex_en_plain_words
    end
  elsif !literal.words? && literal.backslash_delimited?
    if literal.interpolate?
      self.class.lex_en_interp_backslash_delimited
    else
      self.class.lex_en_plain_backslash_delimited
    end
  else
    if literal.interpolate?
      self.class.lex_en_interp_string
    else
      self.class.lex_en_plain_string
    end
  end
end
pop_literal() click to toggle source
# File lib/parser/lexer.rb, line 23774
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 23736
def push_literal(*args)
  new_literal = Literal.new(self, *args)
  @literal_stack.push(new_literal)
  next_state_for_literal(new_literal)
end
range(s = @ts, e = @te) click to toggle source
# File lib/parser/lexer.rb, line 23677
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 23664
def stack_pop
  @top -= 1
  @stack[@top]
end
tok(s = @ts, e = @te) click to toggle source
# File lib/parser/lexer.rb, line 23673
def tok(s = @ts, e = @te)
  @source_buffer.slice(s...e)
end
version?(*versions) click to toggle source
# File lib/parser/lexer.rb, line 23660
def version?(*versions)
  versions.include?(@version)
end