class Parser::Lexer
line 3 “lib/parser/lexer.rl”
BEFORE YOU START ===¶ ↑
Read the Ruby Hacking Guide chapter 11, available in English at whitequark.org/blog/2013/04/01/ruby-hacking-guide-ch-11-finite-state-lexer/
Remember two things about Ragel scanners:
1) Longest match wins. 2) If two matches have the same length, the first in source code wins.
General rules of making Ragel and Bison happy:
* `p` (position) and `@te` contain the index of the character they're pointing to ("current"), plus one. `@ts` contains the index of the corresponding character. The code for extracting matched token is: @source_buffer.slice(@ts...@te) * If your input is `foooooooobar` and the rule is: 'f' 'o'+ the result will be: foooooooobar ^ ts=0 ^ p=te=9 * A Ragel lexer action should not emit more than one token, unless you know what you are doing. * All Ragel commands (fnext, fgoto, ...) end with a semicolon. * If an action emits the token and transitions to another state, use these Ragel commands: emit($whatever) fnext $next_state; fbreak; If you perform `fgoto` in an action which does not emit a token nor rewinds the stream pointer, the parser's side-effectful, context-sensitive lookahead actions will break in a hard to detect and debug way. * If an action does not emit a token: fgoto $next_state; * If an action features lookbehind, i.e. matches characters with the intent of passing them to another action: p = @ts - 1 fgoto $next_state; or, if the lookbehind consists of a single character: fhold; fgoto $next_state; * Ragel merges actions. So, if you have `e_lparen = '(' %act` and `c_lparen = '('` and a lexer action `e_lparen | c_lparen`, the result _will_ invoke the action `act`. e_something stands for "something with **e**mbedded action". * EOF is explicit and is matched by `c_eof`. If you want to introspect the state of the lexer, add this rule to the state: c_eof => do_eof; * If you proceed past EOF, the lexer will complain: NoMethodError: undefined method `ord' for nil:NilClass
Constants
- ESCAPES
line 82 “lib/parser/lexer.rl” %
- KEYWORDS
- KEYWORDS_BEGIN
- LEX_STATES
- PUNCTUATION
Mapping of strings to parser tokens.
- PUNCTUATION_BEGIN
- RBRACE_OR_RBRACK
- REGEXP_META_CHARACTERS
Attributes
_lex_eof_trans[RW]
_lex_from_state_actions[RW]
_lex_index_offsets[RW]
_lex_indicies[RW]
_lex_key_spans[RW]
_lex_to_state_actions[RW]
_lex_trans_actions[RW]
_lex_trans_keys[RW]
_lex_trans_targs[RW]
lex_en_expr_arg[RW]
lex_en_expr_beg[RW]
lex_en_expr_cmdarg[RW]
lex_en_expr_dot[RW]
lex_en_expr_end[RW]
lex_en_expr_endarg[RW]
lex_en_expr_endfn[RW]
lex_en_expr_fname[RW]
lex_en_expr_labelarg[RW]
lex_en_expr_mid[RW]
lex_en_expr_value[RW]
lex_en_expr_variable[RW]
lex_en_interp_backslash_delimited[RW]
lex_en_interp_string[RW]
lex_en_interp_words[RW]
lex_en_leading_dot[RW]
lex_en_line_begin[RW]
lex_en_line_comment[RW]
lex_en_plain_backslash_delimited[RW]
lex_en_plain_string[RW]
lex_en_plain_words[RW]
lex_en_regexp_modifiers[RW]
lex_error[RW]
lex_start[RW]
cmdarg[RW]
comments[RW]
cond[RW]
diagnostics[RW]
force_utf32[RW]
in_kwarg[RW]
source_buffer[R]
static_env[RW]
tokens[RW]
Public Class Methods
new(version)
click to toggle source
# File lib/parser/lexer.rb, line 10610 def initialize(version) @version = version @static_env = nil @tokens = nil @comments = nil reset end
Public Instance Methods
advance()
click to toggle source
Return next token: [type, value].
# File lib/parser/lexer.rb, line 10764 def advance if @token_queue.any? return @token_queue.shift end # Ugly, but dependent on Ragel output. Consider refactoring it somehow. klass = self.class _lex_trans_keys = klass.send :_lex_trans_keys _lex_key_spans = klass.send :_lex_key_spans _lex_index_offsets = klass.send :_lex_index_offsets _lex_indicies = klass.send :_lex_indicies _lex_trans_targs = klass.send :_lex_trans_targs _lex_trans_actions = klass.send :_lex_trans_actions _lex_to_state_actions = klass.send :_lex_to_state_actions _lex_from_state_actions = klass.send :_lex_from_state_actions _lex_eof_trans = klass.send :_lex_eof_trans pe = @source_pts.size + 2 p, eof = @p, pe @command_state = (@cs == klass.lex_en_expr_value || @cs == klass.lex_en_line_begin) # line 10789 "lib/parser/lexer.rb" begin testEof = false _slen, _trans, _keys, _inds, _acts, _nacts = nil _goto_level = 0 _resume = 10 _eof_trans = 15 _again = 20 _test_eof = 30 _out = 40 while true if _goto_level <= 0 if p == pe _goto_level = _test_eof next end if @cs == 0 _goto_level = _out next end end if _goto_level <= _resume case _lex_from_state_actions[ @cs] when 78 then # line 1 "NONE" begin @ts = p end # line 10817 "lib/parser/lexer.rb" end _keys = @cs << 1 _inds = _lex_index_offsets[ @cs] _slen = _lex_key_spans[ @cs] _trans = if ( _slen > 0 && _lex_trans_keys[_keys] <= ( (@source_pts[p] || 0)) && ( (@source_pts[p] || 0)) <= _lex_trans_keys[_keys + 1] ) then _lex_indicies[ _inds + ( (@source_pts[p] || 0)) - _lex_trans_keys[_keys] ] else _lex_indicies[ _inds + _slen ] end end if _goto_level <= _eof_trans @cs = _lex_trans_targs[_trans] if _lex_trans_actions[_trans] != 0 case _lex_trans_actions[_trans] when 26 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end when 97 then # line 766 "lib/parser/lexer.rl" begin @escape_s = p @escape = nil end when 27 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end when 65 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end when 68 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end when 266 then # line 1152 "lib/parser/lexer.rl" begin tm = p end when 34 then # line 1421 "lib/parser/lexer.rl" begin tm = p end when 36 then # line 1437 "lib/parser/lexer.rl" begin tm = p end when 38 then # line 1465 "lib/parser/lexer.rl" begin tm = p end when 53 then # line 1651 "lib/parser/lexer.rl" begin heredoc_e = p end when 306 then # line 1705 "lib/parser/lexer.rl" begin @escape = nil end when 335 then # line 1778 "lib/parser/lexer.rl" begin tm = p end when 411 then # line 1996 "lib/parser/lexer.rl" begin @num_base = 16; @num_digits_s = p end when 405 then # line 1997 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = p end when 408 then # line 1998 "lib/parser/lexer.rl" begin @num_base = 8; @num_digits_s = p end when 402 then # line 1999 "lib/parser/lexer.rl" begin @num_base = 2; @num_digits_s = p end when 417 then # line 2000 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = @ts end when 385 then # line 2001 "lib/parser/lexer.rl" begin @num_base = 8; @num_digits_s = @ts end when 397 then # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 392 then # line 2059 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 390 then # line 2060 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 74 then # line 2195 "lib/parser/lexer.rl" begin tm = p end when 7 then # line 1 "NONE" begin @te = p+1 end when 94 then # line 1007 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DBEG, '#{'.freeze) if current_literal.heredoc? current_literal.saved_herebody_s = @herebody_s @herebody_s = nil end current_literal.start_interp_brace begin @stack[ @top] = @cs @top+= 1 @cs = 747 _goto_level = _again next end end end when 5 then # line 952 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DVAR, nil, @ts, @ts + 1) p = @ts begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 90 then # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 89 then # line 815 "lib/parser/lexer.rl" begin @te = p+1 begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 95 then # line 952 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DVAR, nil, @ts, @ts + 1) p = @ts begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 92 then # line 939 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin literal.extend_space @ts, @te end end when 93 then # line 815 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 6 then # line 839 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 4 then # line 815 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 121 then # line 1007 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DBEG, '#{'.freeze) if current_literal.heredoc? current_literal.saved_herebody_s = @herebody_s @herebody_s = nil end current_literal.start_interp_brace begin @stack[ @top] = @cs @top+= 1 @cs = 747 _goto_level = _again next end end end when 10 then # line 952 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DVAR, nil, @ts, @ts + 1) p = @ts begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 118 then # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 117 then # line 815 "lib/parser/lexer.rl" begin @te = p+1 begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 122 then # line 952 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DVAR, nil, @ts, @ts + 1) p = @ts begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 120 then # line 815 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 11 then # line 839 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 9 then # line 815 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 144 then # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 143 then # line 815 "lib/parser/lexer.rl" begin @te = p+1 begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 146 then # line 939 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin literal.extend_space @ts, @te end end when 147 then # line 815 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 150 then # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 149 then # line 815 "lib/parser/lexer.rl" begin @te = p+1 begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 152 then # line 815 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 159 then # line 1007 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DBEG, '#{'.freeze) if current_literal.heredoc? current_literal.saved_herebody_s = @herebody_s @herebody_s = nil end current_literal.start_interp_brace begin @stack[ @top] = @cs @top+= 1 @cs = 747 _goto_level = _again next end end end when 13 then # line 952 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DVAR, nil, @ts, @ts + 1) p = @ts begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 156 then # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 155 then # line 815 "lib/parser/lexer.rl" begin @te = p+1 begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 160 then # line 952 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal current_literal.flush_string current_literal.extend_content emit(:tSTRING_DVAR, nil, @ts, @ts + 1) p = @ts begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 158 then # line 815 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 12 then # line 815 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 162 then # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 161 then # line 815 "lib/parser/lexer.rl" begin @te = p+1 begin string = tok # tLABEL_END is only possible in non-cond context on >= 2.2 if @version >= 22 && !@cond.active? lookahead = @source_buffer.slice(@te...@te+2) end current_literal = literal if !current_literal.heredoc? && (token = current_literal.nest_and_try_closing(string, @ts, @te, lookahead)) if token[0] == :tLABEL_END p += 1 pop_literal @cs = 740; else @cs = (pop_literal); end begin p += 1 _goto_level = _out next end else current_literal.extend_string(string, @ts, @te) end end end when 164 then # line 1083 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tREGEXP_OPT, tok(@ts, @te - 1), @ts, @te - 1) p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 165 then # line 1071 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin unknown_options = tok.scan(/[^imxouesn]/) if unknown_options.any? diagnostic :error, :regexp_options, { :options => unknown_options.join } end emit(:tREGEXP_OPT) @cs = 755; begin p += 1 _goto_level = _out next end end end when 14 then # line 1211 "lib/parser/lexer.rl" begin @te = p+1 begin if tok =~ /^\$([1-9][0-9]*)$/ emit(:tNTH_REF, tok(@ts + 1).to_i) elsif tok =~ /^\$([&`'+])$/ emit(:tBACK_REF) else emit(:tGVAR) end @cs = (stack_pop); begin p += 1 _goto_level = _out next end end end when 166 then # line 1211 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if tok =~ /^\$([1-9][0-9]*)$/ emit(:tNTH_REF, tok(@ts + 1).to_i) elsif tok =~ /^\$([&`'+])$/ emit(:tBACK_REF) else emit(:tGVAR) end @cs = (stack_pop); begin p += 1 _goto_level = _out next end end end when 168 then # line 1224 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if tok =~ /^@@[0-9]/ diagnostic :error, :cvar_name, { :name => tok } end emit(:tCVAR) @cs = (stack_pop); begin p += 1 _goto_level = _out next end end end when 167 then # line 1234 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if tok =~ /^@[0-9]/ diagnostic :error, :ivar_name, { :name => tok } end emit(:tIVAR) @cs = (stack_pop); begin p += 1 _goto_level = _out next end end end when 189 then # line 1255 "lib/parser/lexer.rl" begin @te = p+1 begin emit_table(KEYWORDS_BEGIN); @cs = 429; begin p += 1 _goto_level = _out next end end end when 175 then # line 1263 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tIDENTIFIER) @cs = 429; begin p += 1 _goto_level = _out next end end end when 16 then # line 1267 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1 @cs = 755; begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 172 then # line 1276 "lib/parser/lexer.rl" begin @te = p+1 begin emit_table(PUNCTUATION) @cs = 429; begin p += 1 _goto_level = _out next end end end when 184 then # line 1280 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 18 then # line 1286 "lib/parser/lexer.rl" begin @te = p+1 begin if version?(23) type, delimiter = tok[0..-2], tok[-1].chr begin @cs = (push_literal(type, delimiter, @ts)) _goto_level = _again next end else p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end end when 171 then # line 1299 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 170 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 188 then # line 1255 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(KEYWORDS_BEGIN); @cs = 429; begin p += 1 _goto_level = _out next end end end when 185 then # line 1259 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tCONSTANT) @cs = 429; begin p += 1 _goto_level = _out next end end end when 187 then # line 1263 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tIDENTIFIER) @cs = 429; begin p += 1 _goto_level = _out next end end end when 182 then # line 1267 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 @cs = 755; begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 178 then # line 1276 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION) @cs = 429; begin p += 1 _goto_level = _out next end end end when 183 then # line 1283 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 176 then # line 1296 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 181 then # line 1299 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 17 then # line 1276 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin emit_table(PUNCTUATION) @cs = 429; begin p += 1 _goto_level = _out next end end end when 15 then # line 1299 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 174 then # line 1 "NONE" begin case @act when 31 then begin begin p = (( @te))-1; end emit_table(KEYWORDS_BEGIN); @cs = 429; begin p += 1 _goto_level = _out next end end when 32 then begin begin p = (( @te))-1; end emit(:tCONSTANT) @cs = 429; begin p += 1 _goto_level = _out next end end when 33 then begin begin p = (( @te))-1; end emit(:tIDENTIFIER) @cs = 429; begin p += 1 _goto_level = _out next end end end end when 20 then # line 1311 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1) p = p - 1; @cs = 740; begin p += 1 _goto_level = _out next end end end when 191 then # line 1317 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 190 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 193 then # line 1314 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 192 then # line 1317 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 19 then # line 1317 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 199 then # line 1343 "lib/parser/lexer.rl" begin @te = p+1 begin emit_table(PUNCTUATION) @cs = 457; begin p += 1 _goto_level = _out next end end end when 198 then # line 1349 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 197 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 209 then # line 1328 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tCONSTANT) @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end when 200 then # line 1332 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tIDENTIFIER) @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end when 205 then # line 1343 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION) @cs = 457; begin p += 1 _goto_level = _out next end end end when 203 then # line 1346 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 208 then # line 1349 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 232 then # line 1407 "lib/parser/lexer.rl" begin @te = p+1 begin # Unlike expr_beg as invoked in the next rule, do not warn p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 215 then # line 1425 "lib/parser/lexer.rl" begin @te = p+1 begin if tok(tm, tm + 1) == '/'.freeze # Ambiguous regexp literal. diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1) end p = tm - 1 begin @cs = 526 _goto_level = _again next end end end when 221 then # line 1449 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 22 then # line 1457 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1; begin @cs = 526 _goto_level = _again next end end end when 223 then # line 1466 "lib/parser/lexer.rl" begin @te = p+1 begin p = tm - 1; begin @cs = 755 _goto_level = _again next end end end when 37 then # line 1475 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 210 then # line 1489 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 211 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 222 then # line 1416 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 218 then # line 1438 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) }, range(tm, @te) p = tm - 1 begin @cs = 526 _goto_level = _again next end end end when 220 then # line 1454 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 214 then # line 1475 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 213 then # line 1480 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 231 then # line 1489 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 23 then # line 1480 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end end when 39 then # line 1489 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 21 then # line 1 "NONE" begin case @act when 59 then begin begin p = (( @te))-1; end if tok(tm, tm + 1) == '/'.freeze # Ambiguous regexp literal. diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1) end p = tm - 1 begin @cs = 526 _goto_level = _again next end end when 60 then begin begin p = (( @te))-1; end diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) }, range(tm, @te) p = tm - 1 begin @cs = 526 _goto_level = _again next end end when 65 then begin begin p = (( @te))-1; end p = @ts - 1 begin @cs = 755 _goto_level = _again next end end else begin begin p = (( @te))-1; end end end end when 41 then # line 1525 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1 begin @cs = 457 _goto_level = _again next end end end when 236 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 237 then # line 1525 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 457 _goto_level = _again next end end end when 42 then # line 1525 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin p = @ts - 1 begin @cs = 457 _goto_level = _again next end end end when 40 then # line 1 "NONE" begin case @act when 72 then begin begin p = (( @te))-1; end if @cond.active? emit(:kDO_COND, 'do'.freeze, @te - 2, @te) else emit(:kDO, 'do'.freeze, @te - 2, @te) end @cs = 747; begin p += 1 _goto_level = _out next end end when 73 then begin begin p = (( @te))-1; end p = @ts - 1 begin @cs = 457 _goto_level = _again next end end end end when 247 then # line 1552 "lib/parser/lexer.rl" begin @te = p+1 begin emit_do(true) @cs = 747; begin p += 1 _goto_level = _out next end end end when 240 then # line 1558 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 241 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 242 then # line 1555 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 245 then # line 1558 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 251 then # line 1582 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 250 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 259 then # line 1574 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1; begin @cs = 526 _goto_level = _again next end end end when 253 then # line 1576 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 257 then # line 1582 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 252 then # line 1 "NONE" begin case @act when 80 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 526; begin p += 1 _goto_level = _out next end end when 81 then begin begin p = (( @te))-1; end p = @ts - 1; begin @cs = 526 _goto_level = _again next end end end end when 287 then # line 1599 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; if tok.start_with? '-'.freeze emit(:tUMINUS_NUM, '-'.freeze, @ts, @ts + 1) @cs = 755; begin p += 1 _goto_level = _out next end end end end when 288 then # line 1619 "lib/parser/lexer.rl" begin @te = p+1 begin type = delimiter = tok[0].chr p = p - 1; begin @cs = (push_literal(type, delimiter, @ts)) _goto_level = _again next end end end when 282 then # line 1626 "lib/parser/lexer.rl" begin @te = p+1 begin type, delimiter = @source_buffer.slice(@ts).chr, tok[-1].chr begin @cs = (push_literal(type, delimiter, @ts)) _goto_level = _again next end end end when 49 then # line 1633 "lib/parser/lexer.rl" begin @te = p+1 begin type, delimiter = tok[0..-2], tok[-1].chr begin @cs = (push_literal(type, delimiter, @ts)) _goto_level = _again next end end end when 289 then # line 1679 "lib/parser/lexer.rl" begin @te = p+1 begin type, delimiter = tok, tok[-1].chr begin @cs = (push_literal(type, delimiter, @ts)) _goto_level = _again next end end end when 52 then # line 1693 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tSYMBOL, tok(@ts + 1), @ts) @cs = 755; begin p += 1 _goto_level = _out next end end end when 303 then # line 1724 "lib/parser/lexer.rl" begin @te = p+1 begin escape = { " " => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t', "\v" => '\v', "\f" => '\f' }[@source_buffer.slice(@ts + 1)] diagnostic :warning, :invalid_escape_use, { :escape => escape }, range p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 302 then # line 1734 "lib/parser/lexer.rl" begin @te = p+1 begin diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1) end end when 290 then # line 1773 "lib/parser/lexer.rl" begin @te = p+1 begin emit_table(PUNCTUATION_BEGIN) begin p += 1 _goto_level = _out next end end end when 46 then # line 1793 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; if version?(18) ident = tok(@ts, @te - 2) emit((@source_buffer.slice(@ts) =~ /[A-Z]/) ? :tCONSTANT : :tIDENTIFIER, ident, @ts, @te - 2) p = p - 1; # continue as a symbol if !@static_env.nil? && @static_env.declared?(ident) @cs = 755; else @cs = (arg_or_cmdarg); end else emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1) @cs = 740; end begin p += 1 _goto_level = _out next end end end when 276 then # line 1839 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1 begin @cs = 161 _goto_level = _again next end end end when 50 then # line 1852 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1; begin @cs = 755 _goto_level = _again next end end end when 262 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 286 then # line 1609 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSTAR, '*'.freeze) begin p += 1 _goto_level = _out next end end end when 283 then # line 1633 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin type, delimiter = tok[0..-2], tok[-1].chr begin @cs = (push_literal(type, delimiter, @ts)) _goto_level = _again next end end end when 281 then # line 1639 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1) end end when 291 then # line 1693 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1), @ts) @cs = 755; begin p += 1 _goto_level = _out next end end end when 301 then # line 1734 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1) end end when 307 then # line 1740 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 284 then # line 1773 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION_BEGIN) begin p += 1 _goto_level = _out next end end end when 329 then # line 1196 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tIDENTIFIER) if !@static_env.nil? && @static_env.declared?(tok) @cs = 429; begin p += 1 _goto_level = _out next end else @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end end when 273 then # line 1836 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 275 then # line 1839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 161 _goto_level = _again next end end end when 278 then # line 1852 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1; begin @cs = 755 _goto_level = _again next end end end when 48 then # line 1639 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1) end end when 55 then # line 1707 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 47 then # line 1836 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end end when 51 then # line 1852 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin p = @ts - 1; begin @cs = 755 _goto_level = _again next end end end when 45 then # line 1 "NONE" begin case @act when 103 then begin begin p = (( @te))-1; end emit_table(PUNCTUATION_BEGIN) begin p += 1 _goto_level = _out next end end when 104 then begin begin p = (( @te))-1; end emit(:kRESCUE, 'rescue'.freeze, @ts, tm) p = tm - 1 @cs = 502; begin p += 1 _goto_level = _out next end end when 105 then begin begin p = (( @te))-1; end emit_table(KEYWORDS_BEGIN) @cs = 747; begin p += 1 _goto_level = _out next end end when 107 then begin begin p = (( @te))-1; end p = @ts - 1 begin @cs = 755 _goto_level = _again next end end when 108 then begin begin p = (( @te))-1; end emit(:tIDENTIFIER) if !@static_env.nil? && @static_env.declared?(tok) @cs = 429; begin p += 1 _goto_level = _out next end else @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end when 111 then begin begin p = (( @te))-1; end p = @ts - 1; begin @cs = 755 _goto_level = _again next end end end end when 337 then # line 1872 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 338 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 339 then # line 1860 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 343 then # line 1872 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 58 then # line 1882 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 347 then # line 1887 "lib/parser/lexer.rl" begin @te = p+1 begin begin @cs = (push_literal(tok, tok, @ts)) _goto_level = _again next end end end when 346 then # line 1897 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 345 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 349 then # line 1891 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 348 then # line 1897 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 57 then # line 1897 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin p = p - 1; begin @cs = 526 _goto_level = _again next end end end when 379 then # line 1908 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tLAMBDA, '->'.freeze, @ts, @ts + 2) @lambda_stack.push @paren_nest @cs = 429; begin p += 1 _goto_level = _out next end end end when 72 then # line 1945 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:kCLASS, 'class'.freeze, @ts, @ts + 5) emit(:tLSHFT, '<<'.freeze, @te - 2, @te) @cs = 747; begin p += 1 _goto_level = _out next end end end when 357 then # line 2080 "lib/parser/lexer.rl" begin @te = p+1 begin type, delimiter = tok, tok[-1].chr begin @cs = (push_literal(type, delimiter, @ts, nil, false, false, true)) _goto_level = _again next end end end when 60 then # line 2098 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1; begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 376 then # line 2105 "lib/parser/lexer.rl" begin @te = p+1 begin emit_table(PUNCTUATION) @cs = 436; begin p += 1 _goto_level = _out next end end end when 370 then # line 2132 "lib/parser/lexer.rl" begin @te = p+1 begin emit_table(PUNCTUATION) @cs = 526; begin p += 1 _goto_level = _out next end end end when 363 then # line 2136 "lib/parser/lexer.rl" begin @te = p+1 begin emit_table(PUNCTUATION) @cond.lexpop; @cmdarg.lexpop if RBRACE_OR_RBRACK.include?(tok) @cs = 494; else # ) # fnext expr_endfn; ? end begin p += 1 _goto_level = _out next end end end when 375 then # line 2150 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tOP_ASGN, tok(@ts, @te - 1)) @cs = 526; begin p += 1 _goto_level = _out next end end end when 361 then # line 2154 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tEH, '?'.freeze) @cs = 747; begin p += 1 _goto_level = _out next end end end when 358 then # line 2162 "lib/parser/lexer.rl" begin @te = p+1 begin emit_table(PUNCTUATION) @cs = 526; begin p += 1 _goto_level = _out next end end end when 360 then # line 2175 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tSEMI, ';'.freeze) @cs = 747; begin p += 1 _goto_level = _out next end end end when 425 then # line 2178 "lib/parser/lexer.rl" begin @te = p+1 begin diagnostic :error, :bare_backslash, nil, range(@ts, @ts + 1) p = p - 1; end end when 356 then # line 2184 "lib/parser/lexer.rl" begin @te = p+1 begin diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } end end when 355 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 435 then # line 1941 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(KEYWORDS) @cs = 316; begin p += 1 _goto_level = _out next end end end when 433 then # line 1945 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:kCLASS, 'class'.freeze, @ts, @ts + 5) emit(:tLSHFT, '<<'.freeze, @te - 2, @te) @cs = 747; begin p += 1 _goto_level = _out next end end end when 432 then # line 1956 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(KEYWORDS) @cs = 747; begin p += 1 _goto_level = _out next end end end when 382 then # line 2030 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin diagnostic :error, :no_dot_digit_literal end end when 422 then # line 2090 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tCONSTANT) @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end when 374 then # line 2098 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1; begin @stack[ @top] = @cs @top+= 1 @cs = 311 _goto_level = _again next end end end when 380 then # line 2105 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION) @cs = 436; begin p += 1 _goto_level = _out next end end end when 427 then # line 1196 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tIDENTIFIER) if !@static_env.nil? && @static_env.declared?(tok) @cs = 429; begin p += 1 _goto_level = _out next end else @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end end when 369 then # line 2132 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION) @cs = 526; begin p += 1 _goto_level = _out next end end end when 381 then # line 2162 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION) @cs = 526; begin p += 1 _goto_level = _out next end end end when 367 then # line 2169 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 373 then # line 2184 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } end end when 61 then # line 2030 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin diagnostic :error, :no_dot_digit_literal end end when 59 then # line 2184 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } end end when 62 then # line 1 "NONE" begin case @act when 124 then begin begin p = (( @te))-1; end if @lambda_stack.last == @paren_nest @lambda_stack.pop if tok == '{'.freeze emit(:tLAMBEG, '{'.freeze) else # 'do' emit(:kDO_LAMBDA, 'do'.freeze) end else if tok == '{'.freeze emit(:tLCURLY, '{'.freeze) else # 'do' emit_do end end @cs = 747; begin p += 1 _goto_level = _out next end end when 125 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 316; begin p += 1 _goto_level = _out next end end when 126 then begin begin p = (( @te))-1; end emit(:kCLASS, 'class'.freeze, @ts, @ts + 5) emit(:tLSHFT, '<<'.freeze, @te - 2, @te) @cs = 747; begin p += 1 _goto_level = _out next end end when 127 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 526; begin p += 1 _goto_level = _out next end end when 128 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 747; begin p += 1 _goto_level = _out next end end when 129 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 502; begin p += 1 _goto_level = _out next end end when 130 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) if version?(18) && tok == 'not'.freeze @cs = 526; begin p += 1 _goto_level = _out next end else @cs = 457; begin p += 1 _goto_level = _out next end end end when 131 then begin begin p = (( @te))-1; end if version?(18) emit(:tIDENTIFIER) unless !@static_env.nil? && @static_env.declared?(tok) @cs = (arg_or_cmdarg); end else emit(:k__ENCODING__, '__ENCODING__'.freeze) end begin p += 1 _goto_level = _out next end end when 132 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) begin p += 1 _goto_level = _out next end end when 133 then begin begin p = (( @te))-1; end digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end when 135 then begin begin p = (( @te))-1; end if version?(18, 19, 20) diagnostic :error, :trailing_in_number, { :character => tok(@te - 1, @te) }, range(@te - 1, @te) else emit(:tINTEGER, tok(@ts, @te - 1).to_i, @ts, @te - 1) p = p - 1; begin p += 1 _goto_level = _out next end end end when 136 then begin begin p = (( @te))-1; end if version?(18, 19, 20) diagnostic :error, :trailing_in_number, { :character => tok(@te - 1, @te) }, range(@te - 1, @te) else emit(:tFLOAT, tok(@ts, @te - 1).to_f, @ts, @te - 1) p = p - 1; begin p += 1 _goto_level = _out next end end end when 137 then begin begin p = (( @te))-1; end digits = tok(@ts, @num_suffix_s) if version?(18, 19, 20) emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits) end begin p += 1 _goto_level = _out next end end when 139 then begin begin p = (( @te))-1; end emit(:tCONSTANT) @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end when 143 then begin begin p = (( @te))-1; end emit(:tIDENTIFIER) if !@static_env.nil? && @static_env.declared?(tok) @cs = 429; begin p += 1 _goto_level = _out next end else @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end when 144 then begin begin p = (( @te))-1; end if tm == @te # Suffix was consumed, e.g. foo! emit(:tFID) else # Suffix was not consumed, e.g. foo!= emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm) p = tm - 1 end @cs = 457; begin p += 1 _goto_level = _out next end end end end when 76 then # line 2196 "lib/parser/lexer.rl" begin @te = p+1 begin p = tm - 1; begin @cs = 755 _goto_level = _again next end end end when 440 then # line 2199 "lib/parser/lexer.rl" begin @te = p+1 begin emit(:tNL, nil, @newline_s, @newline_s + 1) p = p - 1; @cs = 161; begin p += 1 _goto_level = _out next end end end when 441 then # line 2199 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tNL, nil, @newline_s, @newline_s + 1) p = p - 1; @cs = 161; begin p += 1 _goto_level = _out next end end end when 73 then # line 2199 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin emit(:tNL, nil, @newline_s, @newline_s + 1) p = p - 1; @cs = 161; begin p += 1 _goto_level = _out next end end end when 444 then # line 2209 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_comment(@eq_begin_s, @te) begin @cs = 161 _goto_level = _again next end end end when 443 then # line 2217 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin diagnostic :fatal, :embedded_document, nil, range(@eq_begin_s, @eq_begin_s + '=begin'.length) end end when 87 then # line 2227 "lib/parser/lexer.rl" begin @te = p+1 begin @eq_begin_s = @ts begin @cs = 931 _goto_level = _again next end end end when 2 then # line 2231 "lib/parser/lexer.rl" begin @te = p+1 begin p = pe - 3 end end when 79 then # line 2234 "lib/parser/lexer.rl" begin @te = p+1 begin p = p - 1; begin @cs = 747 _goto_level = _again next end end end when 80 then # line 512 "lib/parser/lexer.rl" begin @te = p+1 begin # Sit at EOF indefinitely. #advance would return $eof each time. # This allows to feed the lexer more data if needed; this is only used # in tests. # # Note that this action is not embedded into e_eof like e_heredoc_nl and e_bs # below. This is due to the fact that scanner state at EOF is observed # by tests, and encapsulating it in a rule would break the introspection. p = p - 1; begin p += 1 _goto_level = _out next end end end when 81 then # line 2224 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 86 then # line 2227 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin @eq_begin_s = @ts begin @cs = 931 _goto_level = _again next end end end when 85 then # line 2234 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 747 _goto_level = _again next end end end when 1 then # line 2234 "lib/parser/lexer.rl" begin begin p = (( @te))-1; end begin p = p - 1; begin @cs = 747 _goto_level = _again next end end end when 71 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end when 91 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 119 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 145 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 151 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 157 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 163 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end when 233 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 1407 "lib/parser/lexer.rl" begin @te = p+1 begin # Unlike expr_beg as invoked in the next rule, do not warn p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 224 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 1466 "lib/parser/lexer.rl" begin @te = p+1 begin p = tm - 1; begin @cs = 755 _goto_level = _again next end end end when 216 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 1475 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 304 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 1724 "lib/parser/lexer.rl" begin @te = p+1 begin escape = { " " => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t', "\v" => '\v', "\f" => '\f' }[@source_buffer.slice(@ts + 1)] diagnostic :warning, :invalid_escape_use, { :escape => escape }, range p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 277 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 1839 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1 begin @cs = 161 _goto_level = _again next end end end when 445 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 2209 "lib/parser/lexer.rl" begin @te = p+1 begin emit_comment(@eq_begin_s, @te) begin @cs = 161 _goto_level = _again next end end end when 442 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 2214 "lib/parser/lexer.rl" begin @te = p+1 end when 88 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 2227 "lib/parser/lexer.rl" begin @te = p+1 begin @eq_begin_s = @ts begin @cs = 931 _goto_level = _again next end end end when 3 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 2231 "lib/parser/lexer.rl" begin @te = p+1 begin p = pe - 3 end end when 399 then # line 620 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tRATIONAL, Rational(chars)) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 398 then # line 621 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, chars)) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 400 then # line 622 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Rational(chars))) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 393 then # line 626 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Float(chars))) } end # line 2062 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@ts, @num_suffix_s) if version?(18, 19, 20) emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits) end begin p += 1 _goto_level = _out next end end end when 394 then # line 630 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tRATIONAL, Rational(chars)) } end # line 2062 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@ts, @num_suffix_s) if version?(18, 19, 20) emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits) end begin p += 1 _goto_level = _out next end end end when 395 then # line 631 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tIMAGINARY, Complex(0, Rational(chars))) } end # line 2062 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@ts, @num_suffix_s) if version?(18, 19, 20) emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits) end begin p += 1 _goto_level = _out next end end end when 114 then # line 646 "lib/parser/lexer.rl" begin @escape = "" codepoints = tok(@escape_s + 2, p - 1) codepoint_s = @escape_s + 2 codepoints.split(/[ \t]/).each do |codepoint_str| codepoint = codepoint_str.to_i(16) if codepoint >= 0x110000 diagnostic :error, :unicode_point_too_large, nil, range(codepoint_s, codepoint_s + codepoint_str.length) break end @escape += codepoint.chr(Encoding::UTF_8) codepoint_s += codepoint_str.length + 1 end end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 140 then # line 646 "lib/parser/lexer.rl" begin @escape = "" codepoints = tok(@escape_s + 2, p - 1) codepoint_s = @escape_s + 2 codepoints.split(/[ \t]/).each do |codepoint_str| codepoint = codepoint_str.to_i(16) if codepoint >= 0x110000 diagnostic :error, :unicode_point_too_large, nil, range(codepoint_s, codepoint_s + codepoint_str.length) break end @escape += codepoint.chr(Encoding::UTF_8) codepoint_s += codepoint_str.length + 1 end end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 325 then # line 646 "lib/parser/lexer.rl" begin @escape = "" codepoints = tok(@escape_s + 2, p - 1) codepoint_s = @escape_s + 2 codepoints.split(/[ \t]/).each do |codepoint_str| codepoint = codepoint_str.to_i(16) if codepoint >= 0x110000 diagnostic :error, :unicode_point_too_large, nil, range(codepoint_s, codepoint_s + codepoint_str.length) break end @escape += codepoint.chr(Encoding::UTF_8) codepoint_s += codepoint_str.length + 1 end end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 98 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 124 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 309 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 101 then # line 673 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_escape end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 127 then # line 673 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_escape end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 312 then # line 673 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_escape end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 103 then # line 692 "lib/parser/lexer.rl" begin @escape = "\x7f" end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 129 then # line 692 "lib/parser/lexer.rl" begin @escape = "\x7f" end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 314 then # line 692 "lib/parser/lexer.rl" begin @escape = "\x7f" end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 100 then # line 699 "lib/parser/lexer.rl" begin @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 126 then # line 699 "lib/parser/lexer.rl" begin @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 311 then # line 699 "lib/parser/lexer.rl" begin @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 116 then # line 703 "lib/parser/lexer.rl" begin @escape = encode_escape(tok(@escape_s + 1, p).to_i(16)) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 142 then # line 703 "lib/parser/lexer.rl" begin @escape = encode_escape(tok(@escape_s + 1, p).to_i(16)) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 327 then # line 703 "lib/parser/lexer.rl" begin @escape = encode_escape(tok(@escape_s + 1, p).to_i(16)) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 111 then # line 707 "lib/parser/lexer.rl" begin @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 137 then # line 707 "lib/parser/lexer.rl" begin @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 322 then # line 707 "lib/parser/lexer.rl" begin @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 115 then # line 711 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 141 then # line 711 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 326 then # line 711 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 110 then # line 723 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 136 then # line 723 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 321 then # line 723 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 113 then # line 734 "lib/parser/lexer.rl" begin diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 139 then # line 734 "lib/parser/lexer.rl" begin diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 324 then # line 734 "lib/parser/lexer.rl" begin diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 99 then # line 760 "lib/parser/lexer.rl" begin diagnostic :fatal, :escape_eof, nil, range(p - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 125 then # line 760 "lib/parser/lexer.rl" begin diagnostic :fatal, :escape_eof, nil, range(p - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 310 then # line 760 "lib/parser/lexer.rl" begin diagnostic :fatal, :escape_eof, nil, range(p - 1, p) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 148 then # line 766 "lib/parser/lexer.rl" begin @escape_s = p @escape = nil end # line 839 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 153 then # line 766 "lib/parser/lexer.rl" begin @escape_s = p @escape = nil end # line 839 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 64 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end when 28 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1421 "lib/parser/lexer.rl" begin tm = p end when 30 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1437 "lib/parser/lexer.rl" begin tm = p end when 32 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1465 "lib/parser/lexer.rl" begin tm = p end when 177 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1296 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 196 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1314 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 204 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1346 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 31 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1475 "lib/parser/lexer.rl" begin @te = p+1 begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 235 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1480 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 227 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1486 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 246 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1555 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 258 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1576 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 254 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1579 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = p - 1; begin @cs = 755 _goto_level = _again next end end end when 274 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1836 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 344 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1860 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 340 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1863 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if @in_kwarg p = p - 1; begin @cs = 755 _goto_level = _again next end else begin @cs = 161 _goto_level = _again next end end end end when 353 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1891 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 350 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1894 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin begin @cs = 161 _goto_level = _again next end end end when 426 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 2169 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 368 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 2172 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin begin @cs = 928 _goto_level = _again next end end end when 82 then # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 2224 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 226 then # line 977 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) current_literal = literal if current_literal current_literal.start_interp_brace end end # line 1390 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if @lambda_stack.last == @paren_nest p = @ts - 1 begin @cs = 755 _goto_level = _again next end else emit(:tLCURLY, '{'.freeze, @te - 1, @te) @cs = 747; begin p += 1 _goto_level = _out next end end end end when 248 then # line 977 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) current_literal = literal if current_literal current_literal.start_interp_brace end end # line 1548 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tLBRACE_ARG, '{'.freeze) @cs = 747; end end when 336 then # line 977 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) current_literal = literal if current_literal current_literal.start_interp_brace end end # line 1751 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if @lambda_stack.last == @paren_nest @lambda_stack.pop emit(:tLAMBEG, '{'.freeze) else emit(:tLBRACE, '{'.freeze) end begin p += 1 _goto_level = _out next end end end when 438 then # line 977 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) current_literal = literal if current_literal current_literal.start_interp_brace end end # line 1916 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if @lambda_stack.last == @paren_nest @lambda_stack.pop if tok == '{'.freeze emit(:tLAMBEG, '{'.freeze) else # 'do' emit(:kDO_LAMBDA, 'do'.freeze) end else if tok == '{'.freeze emit(:tLCURLY, '{'.freeze) else # 'do' emit_do end end @cs = 747; begin p += 1 _goto_level = _out next end end end when 439 then # line 986 "lib/parser/lexer.rl" begin current_literal = literal if current_literal if current_literal.end_interp_brace_and_try_closing if version?(18, 19) emit(:tRCURLY, '}'.freeze, p - 1, p) else emit(:tSTRING_DEND, '}'.freeze, p - 1, p) end if current_literal.saved_herebody_s @herebody_s = current_literal.saved_herebody_s end p = p - 1; @cs = (stack_pop); begin p += 1 _goto_level = _out next end end end end # line 2136 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION) @cond.lexpop; @cmdarg.lexpop if RBRACE_OR_RBRACK.include?(tok) @cs = 494; else # ) # fnext expr_endfn; ? end begin p += 1 _goto_level = _out next end end end when 66 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end when 69 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end when 180 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1296 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 195 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1314 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 207 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1346 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 229 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1483 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin begin @cs = 755 _goto_level = _again next end end end when 244 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1555 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 256 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1576 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 280 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1836 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 342 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1860 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 352 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1891 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 372 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 2169 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 84 then # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 2224 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 201 then # line 1152 "lib/parser/lexer.rl" begin tm = p end # line 1336 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tFID, tok(@ts, tm), @ts, tm) @cs = (arg_or_cmdarg); p = tm - 1; begin p += 1 _goto_level = _out next end end end when 292 then # line 1152 "lib/parser/lexer.rl" begin tm = p end # line 1685 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) p = tm - 1 @cs = 755; begin p += 1 _goto_level = _out next end end end when 265 then # line 1152 "lib/parser/lexer.rl" begin tm = p end # line 1824 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 365 then # line 1152 "lib/parser/lexer.rl" begin tm = p end # line 1 "NONE" begin case @act when 124 then begin begin p = (( @te))-1; end if @lambda_stack.last == @paren_nest @lambda_stack.pop if tok == '{'.freeze emit(:tLAMBEG, '{'.freeze) else # 'do' emit(:kDO_LAMBDA, 'do'.freeze) end else if tok == '{'.freeze emit(:tLCURLY, '{'.freeze) else # 'do' emit_do end end @cs = 747; begin p += 1 _goto_level = _out next end end when 125 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 316; begin p += 1 _goto_level = _out next end end when 126 then begin begin p = (( @te))-1; end emit(:kCLASS, 'class'.freeze, @ts, @ts + 5) emit(:tLSHFT, '<<'.freeze, @te - 2, @te) @cs = 747; begin p += 1 _goto_level = _out next end end when 127 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 526; begin p += 1 _goto_level = _out next end end when 128 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 747; begin p += 1 _goto_level = _out next end end when 129 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) @cs = 502; begin p += 1 _goto_level = _out next end end when 130 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) if version?(18) && tok == 'not'.freeze @cs = 526; begin p += 1 _goto_level = _out next end else @cs = 457; begin p += 1 _goto_level = _out next end end end when 131 then begin begin p = (( @te))-1; end if version?(18) emit(:tIDENTIFIER) unless !@static_env.nil? && @static_env.declared?(tok) @cs = (arg_or_cmdarg); end else emit(:k__ENCODING__, '__ENCODING__'.freeze) end begin p += 1 _goto_level = _out next end end when 132 then begin begin p = (( @te))-1; end emit_table(KEYWORDS) begin p += 1 _goto_level = _out next end end when 133 then begin begin p = (( @te))-1; end digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end when 135 then begin begin p = (( @te))-1; end if version?(18, 19, 20) diagnostic :error, :trailing_in_number, { :character => tok(@te - 1, @te) }, range(@te - 1, @te) else emit(:tINTEGER, tok(@ts, @te - 1).to_i, @ts, @te - 1) p = p - 1; begin p += 1 _goto_level = _out next end end end when 136 then begin begin p = (( @te))-1; end if version?(18, 19, 20) diagnostic :error, :trailing_in_number, { :character => tok(@te - 1, @te) }, range(@te - 1, @te) else emit(:tFLOAT, tok(@ts, @te - 1).to_f, @ts, @te - 1) p = p - 1; begin p += 1 _goto_level = _out next end end end when 137 then begin begin p = (( @te))-1; end digits = tok(@ts, @num_suffix_s) if version?(18, 19, 20) emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits) end begin p += 1 _goto_level = _out next end end when 139 then begin begin p = (( @te))-1; end emit(:tCONSTANT) @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end when 143 then begin begin p = (( @te))-1; end emit(:tIDENTIFIER) if !@static_env.nil? && @static_env.declared?(tok) @cs = 429; begin p += 1 _goto_level = _out next end else @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end when 144 then begin begin p = (( @te))-1; end if tm == @te # Suffix was consumed, e.g. foo! emit(:tFID) else # Suffix was not consumed, e.g. foo!= emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm) p = tm - 1 end @cs = 457; begin p += 1 _goto_level = _out next end end end end when 202 then # line 1153 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1336 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tFID, tok(@ts, tm), @ts, tm) @cs = (arg_or_cmdarg); p = tm - 1; begin p += 1 _goto_level = _out next end end end when 293 then # line 1153 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1685 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) p = tm - 1 @cs = 755; begin p += 1 _goto_level = _out next end end end when 267 then # line 1153 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1824 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 366 then # line 1153 "lib/parser/lexer.rl" begin tm = p - 2 end # line 2112 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if tm == @te # Suffix was consumed, e.g. foo! emit(:tFID) else # Suffix was not consumed, e.g. foo!= emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm) p = tm - 1 end @cs = 457; begin p += 1 _goto_level = _out next end end end when 294 then # line 1158 "lib/parser/lexer.rl" begin tm = p end # line 1685 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) p = tm - 1 @cs = 755; begin p += 1 _goto_level = _out next end end end when 268 then # line 1158 "lib/parser/lexer.rl" begin tm = p end # line 1824 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 295 then # line 1159 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1685 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) p = tm - 1 @cs = 755; begin p += 1 _goto_level = _out next end end end when 269 then # line 1159 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1824 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 299 then # line 1160 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1685 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) p = tm - 1 @cs = 755; begin p += 1 _goto_level = _out next end end end when 272 then # line 1160 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1824 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 298 then # line 1161 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1685 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) p = tm - 1 @cs = 755; begin p += 1 _goto_level = _out next end end end when 271 then # line 1161 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1 "NONE" begin case @act when 103 then begin begin p = (( @te))-1; end emit_table(PUNCTUATION_BEGIN) begin p += 1 _goto_level = _out next end end when 104 then begin begin p = (( @te))-1; end emit(:kRESCUE, 'rescue'.freeze, @ts, tm) p = tm - 1 @cs = 502; begin p += 1 _goto_level = _out next end end when 105 then begin begin p = (( @te))-1; end emit_table(KEYWORDS_BEGIN) @cs = 747; begin p += 1 _goto_level = _out next end end when 107 then begin begin p = (( @te))-1; end p = @ts - 1 begin @cs = 755 _goto_level = _again next end end when 108 then begin begin p = (( @te))-1; end emit(:tIDENTIFIER) if !@static_env.nil? && @static_env.declared?(tok) @cs = 429; begin p += 1 _goto_level = _out next end else @cs = (arg_or_cmdarg); begin p += 1 _goto_level = _out next end end end when 111 then begin begin p = (( @te))-1; end p = @ts - 1; begin @cs = 755 _goto_level = _again next end end end end when 296 then # line 1162 "lib/parser/lexer.rl" begin tm = p - 3 end # line 1685 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) p = tm - 1 @cs = 755; begin p += 1 _goto_level = _out next end end end when 270 then # line 1162 "lib/parser/lexer.rl" begin tm = p - 3 end # line 1824 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin p = @ts - 1 begin @cs = 755 _goto_level = _again next end end end when 297 then # line 1167 "lib/parser/lexer.rl" begin tm = p - 2 end # line 1685 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) p = tm - 1 @cs = 755; begin p += 1 _goto_level = _out next end end end when 421 then # line 1172 "lib/parser/lexer.rl" begin tm = p - 2 end # line 2094 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tCONSTANT, tok(@ts, tm), @ts, tm) p = tm - 1; begin p += 1 _goto_level = _out next end end end when 225 then # line 1178 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) end # line 1384 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tLBRACK, '['.freeze, @te - 1, @te) @cs = 526; begin p += 1 _goto_level = _out next end end end when 328 then # line 1178 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) end # line 1763 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tLBRACK, '['.freeze) begin p += 1 _goto_level = _out next end end end when 424 then # line 1178 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) end # line 2158 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tLBRACK2, '['.freeze) @cs = 526; begin p += 1 _goto_level = _out next end end end when 217 then # line 1185 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) @paren_nest += 1 end # line 1365 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin if version?(18) emit(:tLPAREN2, '('.freeze, @te - 1, @te) @cs = 747; begin p += 1 _goto_level = _out next end else emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te) @cs = 526; begin p += 1 _goto_level = _out next end end end end when 230 then # line 1185 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) @paren_nest += 1 end # line 1378 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tLPAREN2, '('.freeze) @cs = 526; begin p += 1 _goto_level = _out next end end end when 238 then # line 1185 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) @paren_nest += 1 end # line 1502 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te) if version?(18) @cs = 747; begin p += 1 _goto_level = _out next end else @cs = 526; begin p += 1 _goto_level = _out next end end end end when 285 then # line 1185 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) @paren_nest += 1 end # line 1768 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:tLPAREN, '('.freeze) begin p += 1 _goto_level = _out next end end end when 377 then # line 1185 "lib/parser/lexer.rl" begin @cond.push(false); @cmdarg.push(false) @paren_nest += 1 end # line 2132 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION) @cs = 526; begin p += 1 _goto_level = _out next end end end when 378 then # line 1191 "lib/parser/lexer.rl" begin @paren_nest -= 1 end # line 2136 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit_table(PUNCTUATION) @cond.lexpop; @cmdarg.lexpop if RBRACE_OR_RBRACK.include?(tok) @cs = 494; else # ) # fnext expr_endfn; ? end begin p += 1 _goto_level = _out next end end end when 54 then # line 1651 "lib/parser/lexer.rl" begin heredoc_e = p end # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end when 300 then # line 1652 "lib/parser/lexer.rl" begin new_herebody_s = p end # line 1653 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin tok(@ts, heredoc_e) =~ /^<<(-?)(~?)(["'`]?)(.*)\3$/ indent = !$1.empty? || !$2.empty? dedent_body = !$2.empty? type = $3.empty? ? '<<"'.freeze : ('<<'.freeze + $3) delimiter = $4 if dedent_body && version?(18, 19, 20, 21, 22) emit(:tLSHFT, '<<'.freeze, @ts, @ts + 2) p = @ts + 1 @cs = 526; begin p += 1 _goto_level = _out next end else @cs = (push_literal(type, delimiter, @ts, heredoc_e, indent, dedent_body)); @herebody_s ||= new_herebody_s p = @herebody_s - 1 end end end when 305 then # line 1705 "lib/parser/lexer.rl" begin @escape = nil end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 332 then # line 1778 "lib/parser/lexer.rl" begin tm = p end # line 1779 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin emit(:kRESCUE, 'rescue'.freeze, @ts, tm) p = tm - 1 @cs = 502; begin p += 1 _goto_level = _out next end end end when 412 then # line 1996 "lib/parser/lexer.rl" begin @num_base = 16; @num_digits_s = p end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 406 then # line 1997 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = p end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 409 then # line 1998 "lib/parser/lexer.rl" begin @num_base = 8; @num_digits_s = p end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 403 then # line 1999 "lib/parser/lexer.rl" begin @num_base = 2; @num_digits_s = p end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 418 then # line 2000 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = @ts end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 387 then # line 2001 "lib/parser/lexer.rl" begin @num_base = 8; @num_digits_s = @ts end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end when 419 then # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end when 75 then # line 2195 "lib/parser/lexer.rl" begin tm = p end # line 2196 "lib/parser/lexer.rl" begin @te = p+1 begin p = tm - 1; begin @cs = 755 _goto_level = _again next end end end when 8 then # line 1 "NONE" begin @te = p+1 end # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end when 186 then # line 1 "NONE" begin @te = p+1 end # line 1255 "lib/parser/lexer.rl" begin @act = 31; end when 173 then # line 1 "NONE" begin @te = p+1 end # line 1259 "lib/parser/lexer.rl" begin @act = 32; end when 169 then # line 1 "NONE" begin @te = p+1 end # line 1263 "lib/parser/lexer.rl" begin @act = 33; end when 24 then # line 1 "NONE" begin @te = p+1 end # line 1425 "lib/parser/lexer.rl" begin @act = 59; end when 219 then # line 1 "NONE" begin @te = p+1 end # line 1438 "lib/parser/lexer.rl" begin @act = 60; end when 25 then # line 1 "NONE" begin @te = p+1 end # line 1475 "lib/parser/lexer.rl" begin @act = 65; end when 212 then # line 1 "NONE" begin @te = p+1 end # line 1480 "lib/parser/lexer.rl" begin @act = 66; end when 239 then # line 1 "NONE" begin @te = p+1 end # line 1512 "lib/parser/lexer.rl" begin @act = 72; end when 43 then # line 1 "NONE" begin @te = p+1 end # line 1525 "lib/parser/lexer.rl" begin @act = 73; end when 260 then # line 1 "NONE" begin @te = p+1 end # line 1570 "lib/parser/lexer.rl" begin @act = 80; end when 249 then # line 1 "NONE" begin @te = p+1 end # line 1574 "lib/parser/lexer.rl" begin @act = 81; end when 263 then # line 1 "NONE" begin @te = p+1 end # line 1773 "lib/parser/lexer.rl" begin @act = 103; end when 331 then # line 1 "NONE" begin @te = p+1 end # line 1779 "lib/parser/lexer.rl" begin @act = 104; end when 330 then # line 1 "NONE" begin @te = p+1 end # line 1785 "lib/parser/lexer.rl" begin @act = 105; end when 56 then # line 1 "NONE" begin @te = p+1 end # line 1824 "lib/parser/lexer.rl" begin @act = 107; end when 261 then # line 1 "NONE" begin @te = p+1 end # line 1196 "lib/parser/lexer.rl" begin @act = 108; end when 264 then # line 1 "NONE" begin @te = p+1 end # line 1852 "lib/parser/lexer.rl" begin @act = 111; end when 434 then # line 1 "NONE" begin @te = p+1 end # line 1916 "lib/parser/lexer.rl" begin @act = 124; end when 429 then # line 1 "NONE" begin @te = p+1 end # line 1941 "lib/parser/lexer.rl" begin @act = 125; end when 437 then # line 1 "NONE" begin @te = p+1 end # line 1951 "lib/parser/lexer.rl" begin @act = 127; end when 430 then # line 1 "NONE" begin @te = p+1 end # line 1956 "lib/parser/lexer.rl" begin @act = 128; end when 431 then # line 1 "NONE" begin @te = p+1 end # line 1960 "lib/parser/lexer.rl" begin @act = 129; end when 436 then # line 1 "NONE" begin @te = p+1 end # line 1964 "lib/parser/lexer.rl" begin @act = 130; end when 428 then # line 1 "NONE" begin @te = p+1 end # line 1975 "lib/parser/lexer.rl" begin @act = 131; end when 423 then # line 1 "NONE" begin @te = p+1 end # line 1989 "lib/parser/lexer.rl" begin @act = 132; end when 359 then # line 1 "NONE" begin @te = p+1 end # line 2003 "lib/parser/lexer.rl" begin @act = 133; end when 389 then # line 1 "NONE" begin @te = p+1 end # line 2047 "lib/parser/lexer.rl" begin @act = 136; end when 63 then # line 1 "NONE" begin @te = p+1 end # line 2062 "lib/parser/lexer.rl" begin @act = 137; end when 362 then # line 1 "NONE" begin @te = p+1 end # line 2090 "lib/parser/lexer.rl" begin @act = 139; end when 354 then # line 1 "NONE" begin @te = p+1 end # line 1196 "lib/parser/lexer.rl" begin @act = 143; end when 364 then # line 1 "NONE" begin @te = p+1 end # line 2112 "lib/parser/lexer.rl" begin @act = 144; end when 154 then # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 877 "lib/parser/lexer.rl" begin @te = p+1 begin current_literal = literal if @te == pe diagnostic :fatal, :string_eof, nil, range(current_literal.str_s, current_literal.str_s + 1) end if current_literal.heredoc? line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) if version?(18, 19, 20) # See ruby:c48b4209c line = line.gsub(/\r.*$/, ''.freeze) end # Try ending the heredoc with the complete most recently # scanned line. @herebody_s always refers to the start of such line. if current_literal.nest_and_try_closing(line, @herebody_s, @ts) # Adjust @herebody_s to point to the next line. @herebody_s = @te # Continue regular lexing after the heredoc reference (<<END). p = current_literal.heredoc_e - 1 @cs = (pop_literal); begin p += 1 _goto_level = _out next end else # Calculate indentation level for <<~HEREDOCs. current_literal.infer_indent_level(line) # Ditto. @herebody_s = @te end else # Try ending the literal with a newline. if current_literal.nest_and_try_closing(tok, @ts, @te) @cs = (pop_literal); begin p += 1 _goto_level = _out next end end if @herebody_s # This is a regular literal intertwined with a heredoc. Like: # # p <<-foo+"1 # bar # foo # 2" # # which, incidentally, evaluates to "bar\n1\n2". p = @herebody_s - 1 @herebody_s = nil end end if current_literal.words? && !eof_codepoint?(@source_pts[p]) current_literal.extend_space @ts, @te else # A literal newline is appended if the heredoc was _not_ closed # this time (see fbreak above). See also Literal#nest_and_try_closing # for rationale of calling #flush_string here. current_literal.extend_string tok, @ts, @te current_literal.flush_string end end end # line 766 "lib/parser/lexer.rl" begin @escape_s = p @escape = nil end when 104 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 130 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 315 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 109 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 135 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 320 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 108 then # line 687 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 134 then # line 687 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 319 then # line 687 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 106 then # line 692 "lib/parser/lexer.rl" begin @escape = "\x7f" end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 132 then # line 692 "lib/parser/lexer.rl" begin @escape = "\x7f" end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 317 then # line 692 "lib/parser/lexer.rl" begin @escape = "\x7f" end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 102 then # line 693 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 128 then # line 693 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 313 then # line 693 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 112 then # line 723 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p) end # line 734 "lib/parser/lexer.rl" begin diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 138 then # line 723 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p) end # line 734 "lib/parser/lexer.rl" begin diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 323 then # line 723 "lib/parser/lexer.rl" begin diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p) end # line 734 "lib/parser/lexer.rl" begin diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 96 then # line 766 "lib/parser/lexer.rl" begin @escape_s = p @escape = nil end # line 760 "lib/parser/lexer.rl" begin diagnostic :fatal, :escape_eof, nil, range(p - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 123 then # line 766 "lib/parser/lexer.rl" begin @escape_s = p @escape = nil end # line 760 "lib/parser/lexer.rl" begin diagnostic :fatal, :escape_eof, nil, range(p - 1, p) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 308 then # line 766 "lib/parser/lexer.rl" begin @escape_s = p @escape = nil end # line 760 "lib/parser/lexer.rl" begin diagnostic :fatal, :escape_eof, nil, range(p - 1, p) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 67 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end when 179 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1296 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 194 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1314 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 206 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1346 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 228 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1483 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin begin @cs = 755 _goto_level = _again next end end end when 243 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1555 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 255 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1576 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 279 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1836 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 341 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1860 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 351 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1891 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 371 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 2169 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 83 then # line 1108 "lib/parser/lexer.rl" begin @sharp_s = p - 1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 2224 "lib/parser/lexer.rl" begin @te = p p = p - 1; end when 414 then # line 2000 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = @ts end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end when 384 then # line 2001 "lib/parser/lexer.rl" begin @num_base = 8; @num_digits_s = @ts end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end when 396 then # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 391 then # line 2059 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 625 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tFLOAT, Float(chars)) } end # line 2062 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@ts, @num_suffix_s) if version?(18, 19, 20) emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits) end begin p += 1 _goto_level = _out next end end end when 388 then # line 2060 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 625 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tFLOAT, Float(chars)) } end # line 2062 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@ts, @num_suffix_s) if version?(18, 19, 20) emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits) end begin p += 1 _goto_level = _out next end end end when 234 then # line 1 "NONE" begin @te = p+1 end # line 486 "lib/parser/lexer.rl" begin # Record position of a newline for precise location reporting on tNL # tokens. # # This action is embedded directly into c_nl, as it is idempotent and # there are no cases when we need to skip it. @newline_s = p end # line 1480 "lib/parser/lexer.rl" begin @act = 66; end when 33 then # line 1 "NONE" begin @te = p+1 end # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1475 "lib/parser/lexer.rl" begin @act = 65; end when 44 then # line 1 "NONE" begin @te = p+1 end # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1525 "lib/parser/lexer.rl" begin @act = 73; end when 70 then # line 1 "NONE" begin @te = p+1 end # line 1111 "lib/parser/lexer.rl" begin emit_comment(@sharp_s, p == pe ? p - 2 : p) end # line 1945 "lib/parser/lexer.rl" begin @act = 126; end when 35 then # line 1 "NONE" begin @te = p+1 end # line 1437 "lib/parser/lexer.rl" begin tm = p end # line 1438 "lib/parser/lexer.rl" begin @act = 60; end when 334 then # line 1 "NONE" begin @te = p+1 end # line 1778 "lib/parser/lexer.rl" begin tm = p end # line 1824 "lib/parser/lexer.rl" begin @act = 107; end when 333 then # line 1 "NONE" begin @te = p+1 end # line 1778 "lib/parser/lexer.rl" begin tm = p end # line 1196 "lib/parser/lexer.rl" begin @act = 108; end when 415 then # line 1 "NONE" begin @te = p+1 end # line 2000 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = @ts end # line 2003 "lib/parser/lexer.rl" begin @act = 133; end when 107 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 133 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 318 then # line 666 "lib/parser/lexer.rl" begin codepoint = @source_pts[p - 1] if (@escape = ESCAPES[codepoint]).nil? @escape = encode_escape(@source_buffer.slice(p - 1)) end end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 105 then # line 693 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 131 then # line 693 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 839 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin current_literal = literal # Get the first character after the backslash. escaped_char = @source_buffer.slice(@escape_s).chr if current_literal.munge_escape? escaped_char # If this particular literal uses this character as an opening # or closing delimiter, it is an escape sequence for that # particular character. Write it without the backslash. if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) # Regular expressions should include escaped delimiters in their # escaped form, except when the escaped character is # a closing delimiter but not a regexp metacharacter. # # The backslash itself cannot be used as a closing delimiter # at the same time as an escape symbol, but it is always munged, # so this branch also executes for the non-closing-delimiter case # for the backslash. current_literal.extend_string(tok, @ts, @te) else current_literal.extend_string(escaped_char, @ts, @te) end else # It does not. So this is an actual escape sequence, yay! if current_literal.regexp? # Regular expressions should include escape sequences in their # escaped form. On the other hand, escaped newlines are removed. current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) else current_literal.extend_string(@escape || tok, @ts, @te) end end end end when 316 then # line 693 "lib/parser/lexer.rl" begin @escape = @source_buffer.slice(p - 1).chr end # line 677 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord & 0x9f) end # line 681 "lib/parser/lexer.rl" begin @escape = encode_escape(@escape[0].ord | 0x80) end # line 1707 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin value = @escape || tok(@ts + 1) if version?(18) if defined?(Encoding) emit(:tINTEGER, value.dup.force_encoding(Encoding::BINARY)[0].ord) else emit(:tINTEGER, value[0].ord) end else emit(:tCHARACTER, value) end @cs = 755; begin p += 1 _goto_level = _out next end end end when 410 then # line 1996 "lib/parser/lexer.rl" begin @num_base = 16; @num_digits_s = p end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 404 then # line 1997 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = p end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 407 then # line 1998 "lib/parser/lexer.rl" begin @num_base = 8; @num_digits_s = p end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 401 then # line 1999 "lib/parser/lexer.rl" begin @num_base = 2; @num_digits_s = p end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 413 then # line 2000 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = @ts end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 383 then # line 2001 "lib/parser/lexer.rl" begin @num_base = 8; @num_digits_s = @ts end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2003 "lib/parser/lexer.rl" begin @te = p p = p - 1; begin digits = tok(@num_digits_s, @num_suffix_s) if digits.end_with? '_'.freeze diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, range(@te - 1, @te) elsif digits.empty? && @num_base == 8 && version?(18) # 1.8 did not raise an error on 0o. digits = '0'.freeze elsif digits.empty? diagnostic :error, :empty_numeric elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) invalid_s = @num_digits_s + invalid_idx diagnostic :error, :invalid_octal, nil, range(invalid_s, invalid_s + 1) end if version?(18, 19, 20) emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) p = @num_suffix_s - 1 else @num_xfrm.call(digits.to_i(@num_base)) end begin p += 1 _goto_level = _out next end end end when 29 then # line 1 "NONE" begin @te = p+1 end # line 806 "lib/parser/lexer.rl" begin # After every heredoc was parsed, @herebody_s contains the # position of next token after all heredocs. if @herebody_s p = @herebody_s @herebody_s = nil end end # line 1437 "lib/parser/lexer.rl" begin tm = p end # line 1438 "lib/parser/lexer.rl" begin @act = 60; end when 420 then # line 1 "NONE" begin @te = p+1 end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2035 "lib/parser/lexer.rl" begin @act = 135; end when 416 then # line 1 "NONE" begin @te = p+1 end # line 2000 "lib/parser/lexer.rl" begin @num_base = 10; @num_digits_s = @ts end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2035 "lib/parser/lexer.rl" begin @act = 135; end when 386 then # line 1 "NONE" begin @te = p+1 end # line 2001 "lib/parser/lexer.rl" begin @num_base = 8; @num_digits_s = @ts end # line 2002 "lib/parser/lexer.rl" begin @num_suffix_s = p end # line 619 "lib/parser/lexer.rl" begin @num_xfrm = lambda { |chars| emit(:tINTEGER, chars) } end # line 2035 "lib/parser/lexer.rl" begin @act = 135; end # line 20792 "lib/parser/lexer.rb" end end end if _goto_level <= _again case _lex_to_state_actions[ @cs] when 77 then # line 1 "NONE" begin @ts = nil; end # line 20802 "lib/parser/lexer.rb" end if @cs == 0 _goto_level = _out next end p += 1 if p != pe _goto_level = _resume next end end if _goto_level <= _test_eof if p == eof if _lex_eof_trans[ @cs] > 0 _trans = _lex_eof_trans[ @cs] - 1; _goto_level = _eof_trans next; end end end if _goto_level <= _out break end end end # line 282 "lib/parser/lexer.rl" # % @p = p if @token_queue.any? @token_queue.shift elsif @cs == klass.lex_error [ false, [ '$error'.freeze, range(p - 1, p) ] ] else eof = @source_pts.size [ false, [ '$eof'.freeze, range(eof, eof) ] ] end end
dedent_level()
click to toggle source
# File lib/parser/lexer.rb, line 10756 def dedent_level # We erase @dedent_level as a precaution to avoid accidentally # using a stale value. dedent_level, @dedent_level = @dedent_level, nil dedent_level end
encoding()
click to toggle source
# File lib/parser/lexer.rb, line 10706 def encoding @source_buffer.source.encoding end
pop_cmdarg()
click to toggle source
# File lib/parser/lexer.rb, line 10743 def pop_cmdarg @cmdarg = @cmdarg_stack.pop end
pop_cond()
click to toggle source
# File lib/parser/lexer.rb, line 10752 def pop_cond @cond = @cond_stack.pop end
push_cmdarg()
click to toggle source
# File lib/parser/lexer.rb, line 10738 def push_cmdarg @cmdarg_stack.push(@cmdarg) @cmdarg = StackState.new("cmdarg.#{@cmdarg_stack.count}") end
push_cond()
click to toggle source
# File lib/parser/lexer.rb, line 10747 def push_cond @cond_stack.push(@cond) @cond = StackState.new("cond.#{@cond_stack.count}") end
reset(reset_state=true)
click to toggle source
# File lib/parser/lexer.rb, line 10620 def reset(reset_state=true) # Ragel state: if reset_state # Unit tests set state prior to resetting lexer. @cs = self.class.lex_en_line_begin @cond = StackState.new('cond') @cmdarg = StackState.new('cmdarg') @cond_stack = [] @cmdarg_stack = [] end @force_utf32 = false # Set to true by some tests @source_pts = nil # @source as a codepoint array @p = 0 # stream position (saved manually in #advance) @ts = nil # token start @te = nil # token end @act = 0 # next action @stack = [] # state stack @top = 0 # state stack top pointer # Lexer state: @token_queue = [] @literal_stack = [] @eq_begin_s = nil # location of last encountered =begin @sharp_s = nil # location of last encountered # @newline_s = nil # location of last encountered newline @num_base = nil # last numeric base @num_digits_s = nil # starting position of numeric digits @num_suffix_s = nil # starting position of numeric suffix @num_xfrm = nil # numeric suffix-induced transformation @escape_s = nil # starting position of current sequence @escape = nil # last escaped sequence, as string @herebody_s = nil # starting position of current heredoc line # Ruby 1.9 ->() lambdas emit a distinct token if do/{ is # encountered after a matching closing parenthesis. @paren_nest = 0 @lambda_stack = [] # After encountering the closing line of <<~SQUIGGLY_HEREDOC, # we store the indentation level and give it out to the parser # on request. It is not possible to infer indentation level just # from the AST because escape sequences such as `\ ` or `\t` are # expanded inside the lexer, but count as non-whitespace for # indentation purposes. @dedent_level = nil # If the lexer is in `command state' (aka expr_value) # at the entry to #advance, it will transition to expr_cmdarg # instead of expr_arg at certain points. @command_state = false # True at the end of "def foo a:" @in_kwarg = false end
source_buffer=(source_buffer)
click to toggle source
# File lib/parser/lexer.rb, line 10685 def source_buffer=(source_buffer) @source_buffer = source_buffer if @source_buffer source = @source_buffer.source if defined?(Encoding) && source.encoding == Encoding::UTF_8 @source_pts = source.unpack('U*') else @source_pts = source.unpack('C*') end if @source_pts[0] == 0xfeff # Skip byte order mark. @p = 1 end else @source_pts = nil end end
state()
click to toggle source
# File lib/parser/lexer.rb, line 10730 def state LEX_STATES.invert.fetch(@cs, @cs) end
state=(state)
click to toggle source
# File lib/parser/lexer.rb, line 10734 def state=(state) @cs = LEX_STATES.fetch(state) end
Protected Instance Methods
arg_or_cmdarg()
click to toggle source
# File lib/parser/lexer.rb, line 20904 def arg_or_cmdarg if @command_state self.class.lex_en_expr_cmdarg else self.class.lex_en_expr_arg end end
diagnostic(type, reason, arguments=nil, location=range, highlights=[])
click to toggle source
# File lib/parser/lexer.rb, line 20924 def diagnostic(type, reason, arguments=nil, location=range, highlights=[]) @diagnostics.process( Parser::Diagnostic.new(type, reason, arguments, location, highlights)) end
emit(type, value = tok, s = @ts, e = @te)
click to toggle source
# File lib/parser/lexer.rb, line 20878 def emit(type, value = tok, s = @ts, e = @te) token = [ type, [ value, range(s, e) ] ] @token_queue.push(token) @tokens.push(token) if @tokens token end
emit_comment(s = @ts, e = @te)
click to toggle source
# File lib/parser/lexer.rb, line 20912 def emit_comment(s = @ts, e = @te) if @comments @comments.push(Parser::Source::Comment.new(range(s, e))) end if @tokens @tokens.push([ :tCOMMENT, [ tok(s, e), range(s, e) ] ]) end nil end
emit_do(do_block=false)
click to toggle source
# File lib/parser/lexer.rb, line 20894 def emit_do(do_block=false) if @cond.active? emit(:kDO_COND, 'do'.freeze) elsif @cmdarg.active? || do_block emit(:kDO_BLOCK, 'do'.freeze) else emit(:kDO, 'do'.freeze) end end
emit_table(table, s = @ts, e = @te)
click to toggle source
# File lib/parser/lexer.rb, line 20888 def emit_table(table, s = @ts, e = @te) value = tok(s, e) emit(table[value], value, s, e) end
encode_escape(ord)
click to toggle source
# File lib/parser/lexer.rb, line 20861 def encode_escape(ord) ord.chr.force_encoding(@source_buffer.source.encoding) end
eof_codepoint?(point)
click to toggle source
# File lib/parser/lexer.rb, line 20847 def eof_codepoint?(point) [0x04, 0x1a, 0x00].include? point end
literal()
click to toggle source
# File lib/parser/lexer.rb, line 20958 def literal @literal_stack.last end
pop_literal()
click to toggle source
# File lib/parser/lexer.rb, line 20962 def pop_literal old_literal = @literal_stack.pop @dedent_level = old_literal.dedent_level if old_literal.type == :tREGEXP_BEG # Fetch modifiers. self.class.lex_en_regexp_modifiers else self.class.lex_en_expr_end end end
push_literal(*args)
click to toggle source
LITERAL STACK ===¶ ↑
# File lib/parser/lexer.rb, line 20933 def push_literal(*args) new_literal = Literal.new(self, *args) @literal_stack.push(new_literal) if new_literal.words? if new_literal.interpolate? self.class.lex_en_interp_words else self.class.lex_en_plain_words end elsif new_literal.backslash_delimited? if new_literal.interpolate? self.class.lex_en_interp_backslash_delimited else self.class.lex_en_plain_backslash_delimited end else if new_literal.interpolate? self.class.lex_en_interp_string else self.class.lex_en_plain_string end end end
range(s = @ts, e = @te)
click to toggle source
# File lib/parser/lexer.rb, line 20874 def range(s = @ts, e = @te) Parser::Source::Range.new(@source_buffer, s, e) end
stack_pop()
click to toggle source
# File lib/parser/lexer.rb, line 20855 def stack_pop @top -= 1 @stack[@top] end
tok(s = @ts, e = @te)
click to toggle source
# File lib/parser/lexer.rb, line 20870 def tok(s = @ts, e = @te) @source_buffer.slice(s...e) end
version?(*versions)
click to toggle source
# File lib/parser/lexer.rb, line 20851 def version?(*versions) versions.include?(@version) end