X-Git-Url: https://code.kerkeslager.com/?a=blobdiff_plain;ds=sidebyside;f=don%2Fstring.py;h=0162d42ed844b1c9400d7bc21365dc79c1b16903;hb=84cf65f13614f1ba0ef1b37217a71b46a3b8827a;hp=1e930ac80164caaf6210e6eaa4880db25fcad5de;hpb=b39b9e38fbf76288624846e1a29a99074db7e627;p=ton diff --git a/don/string.py b/don/string.py index 1e930ac..0162d42 100644 --- a/don/string.py +++ b/don/string.py @@ -106,6 +106,7 @@ def _make_integer_parser(width): _BINARY32_MATCHER = re.compile(r'(-?\d+\.\d+)f') _BINARY64_MATCHER = re.compile(r'(-?\d+\.\d+)d') +@_consume_leading_whitespace def _binary32_parser(s): match = _BINARY32_MATCHER.match(s) @@ -119,6 +120,7 @@ def _binary32_parser(s): return _shared._FAILED_PARSE_RESULT +@_consume_leading_whitespace def _binary64_parser(s): match = _BINARY64_MATCHER.match(s) @@ -134,6 +136,7 @@ def _binary64_parser(s): _BINARY_MATCHER = re.compile(r'"([\da-f]*)"b') +@_consume_leading_whitespace def _binary_parser(s): match = _BINARY_MATCHER.match(s) @@ -149,7 +152,8 @@ def _binary_parser(s): def _make_utf_parser(encoding): matcher = re.compile(r'"(.*?)"' + encoding) - def parser(s): + @_consume_leading_whitespace + def utf_parser(s): match = matcher.match(s) if match: @@ -161,29 +165,48 @@ def _make_utf_parser(encoding): return _shared._FAILED_PARSE_RESULT - return parser + return utf_parser + +def _make_consume_constant_parser(constant): + @_consume_leading_whitespace + def consume_character_parser(s): + if s.startswith(constant): + return _shared.ParseResult( + success = True, + value = None, + remaining = s[len(constant):], + ) + return _shared._FAILED_PARSE_RESULT + + return consume_character_parser + +_consume_comma_parser = _make_consume_constant_parser(',') def _prefix_with_comma(parser): def wrapped(s): - if s.startswith(','): - s = s[1:] + result = _consume_comma_parser(s) + if result.success: + s = result.remaining + else: + return _shared._FAILED_PARSE_RESULT - result = parser(s) - if not result.success: - raise Exception('Trailing comma before "{}"'.format(s)) + result = parser(s) + if not result.success: + raise Exception('Trailing comma before "{}"'.format(s)) - return result - - return _shared._FAILED_PARSE_RESULT + return result return wrapped def _comma_separate_and_wrap(wrapped_parser, start_wrap, end_wrap, typecaster): parser_prefixed_with_comma = _prefix_with_comma(wrapped_parser) + start_wrap_parser = _make_consume_constant_parser(start_wrap) + end_wrap_parser = _make_consume_constant_parser(end_wrap) def parser(s): - if s.startswith(start_wrap): - s = s[1:] + result = start_wrap_parser(s) + if result.success: + s = result.remaining else: return _shared._FAILED_PARSE_RESULT @@ -197,8 +220,9 @@ def _comma_separate_and_wrap(wrapped_parser, start_wrap, end_wrap, typecaster): s = parse_result.remaining parse_result = parser_prefixed_with_comma(s) - if s.startswith(end_wrap): - s = s[1:] + result = end_wrap_parser(s) + if result.success: + s = result.remaining else: return _shared._FAILED_PARSE_RESULT @@ -223,6 +247,8 @@ def _object_parser(source): _list_parser = _comma_separate_and_wrap(_object_parser, '[', ']', list) +_consume_colon_parser = _make_consume_constant_parser(':') + def _kvp_parser(s): key_parse_result = _object_parser(s) if key_parse_result.success: @@ -230,8 +256,9 @@ def _kvp_parser(s): else: return _shared._FAILED_PARSE_RESULT - if s.startswith(':'): - s = s[1:] + result = _consume_colon_parser(s) + if result.success: + s = result.remaining else: return _shared._FAILED_PARSE_RESULT