123456789_123456789_123456789_123456789_123456789_

Module: Net::IMAP::ResponseParser::ParserUtils

Do not use. This module is for internal use only.
Relationships & Source Files
Namespace Children
Modules:
Extension / Inclusion / Inheritance Descendants
Included In:
Defined in: lib/net/imap/response_parser/parser_utils.rb

Overview

basic utility methods for parsing.

(internal API, subject to change)

Instance Method Summary

Instance Method Details

#accept(*args) (private)

like match, but does not raise error on failure.

returns and shifts token on successful match returns nil and leaves @token unshifted on no match

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 148

def accept(*args)
  token = lookahead
  if args.include?(token.symbol)
    shift_token
    token
  end
end

#accept_re(re) (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 198

def accept_re(re)
  assert_no_lookahead if config.debug?
  re.match(@str, @pos) and @pos = $~.end(0)
  $~
end

#assert_no_lookahead (private)

To be used conditionally:

assert_no_lookahead if config.debug?
[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 158

def assert_no_lookahead
  @token.nil? or
    parse_error("assertion failed: expected @token.nil?, actual %s: %p",
                @token.symbol, @token.value)
end

#combine_adjacent(*tokens) (private)

TODO: after checking the lookahead, use a regexp for remaining chars. That way a loop isn’t needed.

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 121

def combine_adjacent(*tokens)
  result = "".b
  while token = accept(*tokens)
    result << token.value
  end
  if result.empty?
    parse_error('unexpected token %s (expected %s)',
                lookahead.symbol, tokens.join(" or "))
  end
  result
end

#current_state (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 230

def current_state        = [@lex_state, @pos, @token]

#exception(message) (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 220

def exception(message) = ResponseParseError.new(
  message, parser_state:, parser_class: self.class
)

#lookahead (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 169

def lookahead
  @token ||= next_token
end

#lookahead!(*args) (private)

like match, without consuming the token

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 174

def lookahead!(*args)
  if args.include?((@token ||= next_token)&.symbol)
    @token
  else
    parse_error('unexpected token %s (expected %s)',
                @token&.symbol, args.join(" or "))
  end
end

#lookahead?(*symbols) ⇒ Boolean (private)

like accept, without consuming the token

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 165

def lookahead?(*symbols)
  @token if symbols.include?((@token ||= next_token)&.symbol)
end

#match(*args) (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 133

def match(*args)
  token = lookahead
  unless args.include?(token.symbol)
    parse_error('unexpected token %s (expected %s)',
                token.symbol.id2name,
                args.collect {|i| i.id2name}.join(" or "))
  end
  shift_token
  token
end

#match_re(re, name) (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 204

def match_re(re, name)
  assert_no_lookahead if config.debug?
  if re.match(@str, @pos)
    @pos = $~.end(0)
    $~
  else
    parse_error("invalid #{name}")
  end
end

#parse_error(fmt, *args) (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 218

def parse_error(fmt, *args) = raise exception format(fmt, *args)

#parser_state (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 231

def parser_state         = [@str, *current_state]

#peek_re(re) (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 193

def peek_re(re)
  assert_no_lookahead if config.debug?
  re.match(@str, @pos)
end

#peek_re?(re) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 188

def peek_re?(re)
  assert_no_lookahead if Net::IMAP.debug
  re.match?(@str, @pos)
end

#peek_str?(str) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 183

def peek_str?(str)
  assert_no_lookahead if config.debug?
  @str[@pos, str.length] == str
end

#restore_state(state) (private)

This can be used to backtrack after a parse error, and re-attempt to parse using a fallback.

NOTE: Reckless backtracking could lead to O(n²) situations, so this should very rarely be used. Ideally, fallbacks should not backtrack.

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 229

def restore_state(state) = (@lex_state, @pos, @token = state)

#shift_token (private)

[ GitHub ]

  
# File 'lib/net/imap/response_parser/parser_utils.rb', line 214

def shift_token
  @token = nil
end