From f62775a31cc1ae5f7e8fb0466feca3cb86dee651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= <hugo@lysator.liu.se> Date: Sat, 16 Sep 2023 03:08:02 +0200 Subject: [PATCH] Change `char` in parser combinator. --- muppet/parser_combinator.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/muppet/parser_combinator.py b/muppet/parser_combinator.py index 8b58d1c..fa7ca95 100644 --- a/muppet/parser_combinator.py +++ b/muppet/parser_combinator.py @@ -194,7 +194,7 @@ logger = logging.getLogger(__name__) @dataclass(kw_only=True) -class MatchObject: +class MatchCompound: """A matched item, similar to a regex match.""" type: str @@ -204,7 +204,10 @@ class MatchObject: if self.type: return f'`{self.type}({self.matched!r})`' else: - return f'MatchObject({self.matched!r}))' + return f'MatchCompound({self.matched!r}))' + + +MatchObject: TypeAlias = MatchCompound | str @dataclass @@ -521,13 +524,7 @@ class CharParser(ParseDirective): """Parse a single character.""" def run(self, parser: 'ParserCombinator') -> list[MatchObject]: # noqa: D102 - out: list[MatchObject] - try: - out = [parser._ParserCombinator__source[parser.seek]] - except IndexError: - raise ParseError("End of string") - parser.seek += 1 - return out + return [parser._get_char()] def __repr__(self) -> str: return 'char' @@ -645,7 +642,7 @@ class tag(ParseDirective): def run(self, parser: 'ParserCombinator') -> list[MatchObject]: # noqa: D102 result = parser.get(self.parser) - return [MatchObject(type=self.tag, matched=result)] + return [MatchCompound(type=self.tag, matched=result)] # @dataclass @@ -739,6 +736,24 @@ class ParserCombinator: self.restore(snapshot) return result + def _get_char(self) -> str: + """ + Primitive for reading one character. + + This method reads one character from the buffer and returns + it, or raises an IndexError if we are at the end of the + buffer. + + This procedure shouldn't be called directly, but instead the + parser ``char`` should be invoked. + """ + try: + out = self.__source[self.seek] + except IndexError: + raise ParseError("End of string") + self.seek += 1 + return out + def remaining(self) -> str: """Return remaining, unparsed, string.""" return self.__source[self.seek:] -- GitLab