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