module Net::IMAP::ResponseParser::ParserUtils::Generator
Constants
- LOOKAHEAD
- SHIFT_TOKEN
Public Instance Methods
def_char_matchers(name, char, token)
click to toggle source
we can skip lexer for single character matches, as a shortcut
# File net-imap-0.4.4/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)
click to toggle source
TODO: move coersion to the token.value method?
# File net-imap-0.4.4/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