diff --git a/muppet/parser_combinator.py b/muppet/parser_combinator.py index 8b58d1c4e545fdd6faa9f175c37281325a45e4d0..fa7ca95b249334f7fa6958e35a78d57a483fafdf 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:]