From e824ee1564806359b580cb7f9975dc8f0aaa2e73 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Sat, 1 May 2021 04:13:08 -0600 Subject: fetch message contents this still has some duplicates and breaks on MIME Content-Transfer-Encoding: 8bit but like. that's life --- ctec/parse_utils.py | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'ctec/parse_utils.py') diff --git a/ctec/parse_utils.py b/ctec/parse_utils.py index fe3ed06..890d36f 100644 --- a/ctec/parse_utils.py +++ b/ctec/parse_utils.py @@ -1,4 +1,4 @@ -from typing import Callable, List, Optional, Tuple, TypeVar +from typing import Callable, List, Optional, Tuple, TypeVar, Sequence __all__ = [ 'ParseResult', @@ -19,6 +19,7 @@ __all__ = [ 'verify', 'many0', 'many1', + 'many_m_n', 'delimited', 'pair', 'triple', @@ -27,6 +28,8 @@ __all__ = [ 'separated_pair', 'separated_triple', 'separated_many0', + 'separated_many1', + 'string_concat', ] T = TypeVar('T') @@ -178,6 +181,25 @@ def many1(parser: Parser[T]) -> Parser[List[T]]: return result, extra return parse +def many_m_n(parser: Parser[T], min_inclusive: int, max_inclusive: int) -> Parser[List[T]]: + def parse(text: str) -> ParseResult[List[T]]: + result: List[T] = [] + while len(result) < min_inclusive: + parser_result = parser(text) + if parser_result is None: + return None + this_result, text = parser_result + result.append(this_result) + + while len(result) < max_inclusive: + parser_result = parser(text) + if parser_result is None: + break + this_result, text = parser_result + result.append(this_result) + return result, text + return parse + def separated_many0(parser: Parser[T], separator_parser: Parser) -> Parser[List[T]]: def parse(text: str) -> ParseResult[List[T]]: result = [] @@ -195,6 +217,9 @@ def separated_many0(parser: Parser[T], separator_parser: Parser) -> Parser[List[ return result, text return parse +def separated_many1(parser: Parser[T], separator_parser: Parser) -> Parser[List[T]]: + return verify(separated_many0(parser, separator_parser), lambda result: len(result) > 0) + def delimited(before_parser: Parser[T1], parser: Parser[T], after_parser: Parser[T2]) -> Parser[T]: def parse(text: str) -> ParseResult[T]: before_result = before_parser(text) @@ -251,10 +276,14 @@ def triple(first_parser: Parser[T1], second_parser: Parser[T2], third_parser: Pa return parse def preceded(before_parser: Parser[T1], parser: Parser[T]) -> Parser[T]: - return map_parser(pair(before_parser, parser), lambda x: x[1]) + def second(x: Tuple[T1, T]) -> T: + return x[1] + return map_parser(pair(before_parser, parser), second) def followed(parser: Parser[T], after_parser: Parser[T1]) -> Parser[T]: - return map_parser(pair(parser, after_parser), lambda x: x[0]) + def first(x: Tuple[T, T1]) -> T: + return x[0] + return map_parser(pair(parser, after_parser), first) def separated_pair(first_parser: Parser[T1], between_parser: Parser[T], second_parser: Parser[T2]) -> Parser[Tuple[T1, T2]]: def parse(text: str) -> ParseResult[Tuple[T1, T2]]: @@ -305,3 +334,6 @@ def separated_triple(first_parser: Parser[T1], between12_parser: Parser, second_ return (first_result, second_result, third_result), extra return parse + +def string_concat(parser: Parser[Sequence[str]]) -> Parser[str]: + return map_parser(parser, ''.join) -- cgit v1.2.3