Module: Net::IMAP::ResponseParser::ParserUtils::Generator
Do not use. This module is for internal use only.
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Extended In:
| |
Defined in: | lib/net/imap/response_parser/parser_utils.rb |
Constant Summary
-
LOOKAHEAD =
# File 'lib/net/imap/response_parser/parser_utils.rb', line 13"(@token ||= next_token)"
-
SHIFT_TOKEN =
# File 'lib/net/imap/response_parser/parser_utils.rb', line 14"(@token = nil)"
Instance Method Summary
-
#def_char_matchers(name, char, token)
we can skip lexer for single character matches, as a shortcut.
-
#def_token_matchers(name, *token_symbols, coerce: nil, send: nil)
TODO: move coersion to the token.value method?
Instance Method Details
#def_char_matchers(name, char, token)
we can skip lexer for single character matches, as a shortcut
# File 'lib/net/imap/response_parser/parser_utils.rb', line 17
def def_char_matchers(name, char, token) byte = char.ord match_name = name.match(/\A[A-Z]/) ? "#{name}!" : name char = char.dump class_eval <<~RUBY, __FILE__, __LINE__ + 1 # frozen_string_literal: true # force use of #next_token; no string peeking def lookahead_#{name}? #{LOOKAHEAD}&.symbol == #{token} end # use token or string peek def peek_#{name}? @token ? @token.symbol == #{token} : @str.getbyte(@pos) == #{byte} end # like accept(token_symbols); returns token or nil def #{name}? if @token&.symbol == #{token} #{SHIFT_TOKEN} #{char} elsif !@token && @str.getbyte(@pos) == #{byte} @pos += 1 #{char} end end # like match(token_symbols); returns token or raises parse_error def #{match_name} if @token&.symbol == #{token} #{SHIFT_TOKEN} #{char} elsif !@token && @str.getbyte(@pos) == #{byte} @pos += 1 #{char} else parse_error("unexpected %s (expected %p)", @token&.symbol || @str[@pos].inspect, #{char}) end end RUBY end
#def_token_matchers(name, *token_symbols, coerce: nil, send: nil)
TODO: move coersion to the token.value method?
# File 'lib/net/imap/response_parser/parser_utils.rb', line 62
def def_token_matchers(name, *token_symbols, coerce: nil, send: nil) match_name = name.match(/\A[A-Z]/) ? "#{name}!" : name if token_symbols.size == 1 token = token_symbols.first matcher = "token&.symbol == %p" % [token] desc = token else matcher = "%p.include? token&.symbol" % [token_symbols] desc = token_symbols.join(" or ") end value = "(token.value)" value = coerce.to_s + value if coerce value = [value, send].join(".") if send raise_parse_error = <<~RUBY parse_error("unexpected %s (expected #{desc})", token&.symbol) RUBY class_eval <<~RUBY, __FILE__, __LINE__ + 1 # frozen_string_literal: true # lookahead version of match, returning the value def lookahead_#{name}! token = #{LOOKAHEAD} if #{matcher} #{value} else #{raise_parse_error} end end def #{name}? token = #{LOOKAHEAD} if #{matcher} #{SHIFT_TOKEN} #{value} end end def #{match_name} token = #{LOOKAHEAD} if #{matcher} #{SHIFT_TOKEN} #{value} else #{raise_parse_error} end end RUBY end