aboutsummaryrefslogtreecommitdiff
path: root/ctec/parse_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'ctec/parse_utils.py')
-rw-r--r--ctec/parse_utils.py38
1 files changed, 35 insertions, 3 deletions
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)