Module: Net::IMAP::ResponseParser::ParserUtils
| 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
-
#accept(*args)
private
like match, but does not raise error on failure.
- #accept_re(re) private
-
#assert_no_lookahead
private
To be used conditionally:
-
#combine_adjacent(*tokens)
private
TODO: after checking the lookahead, use a regexp for remaining chars.
- #current_state private
- #exception(message) private
- #lookahead private
-
#lookahead!(*args)
private
like match, without consuming the token.
-
#lookahead?(*symbols) ⇒ Boolean
private
like accept, without consuming the token.
- #match(*args) private
- #match_re(re, name) private
- #parse_error(fmt, *args) private
- #parser_state private
- #peek_re(re) private
- #peek_re?(re) ⇒ Boolean private
- #peek_str?(str) ⇒ Boolean private
-
#restore_state(state)
private
This can be used to backtrack after a parse error, and re-attempt to parse using a fallback.
- #shift_token private
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
# 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?
# 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.
# 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() = ResponseParseError.new( , 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
# 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
# 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)
# 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)
# 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.
# 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