| 67 | |
| 68 | |
| 69 | class Reader: |
| 70 | def __init__(self, stream: IO[str]) -> None: |
| 71 | self.string = stream.read() |
| 72 | self.position = Position.start() |
| 73 | self.mark = Position.start() |
| 74 | |
| 75 | def has_next(self) -> bool: |
| 76 | return self.position.chars < len(self.string) |
| 77 | |
| 78 | def set_mark(self) -> None: |
| 79 | self.mark.set(self.position) |
| 80 | |
| 81 | def get_marked(self) -> Original: |
| 82 | return Original( |
| 83 | string=self.string[self.mark.chars : self.position.chars], |
| 84 | line=self.mark.line, |
| 85 | ) |
| 86 | |
| 87 | def peek(self, count: int) -> str: |
| 88 | return self.string[self.position.chars : self.position.chars + count] |
| 89 | |
| 90 | def read(self, count: int) -> str: |
| 91 | result = self.string[self.position.chars : self.position.chars + count] |
| 92 | if len(result) < count: |
| 93 | raise Error("read: End of string") |
| 94 | self.position.advance(result) |
| 95 | return result |
| 96 | |
| 97 | def read_regex(self, regex: Pattern[str]) -> Sequence[str]: |
| 98 | match = regex.match(self.string, self.position.chars) |
| 99 | if match is None: |
| 100 | raise Error("read_regex: Pattern not found") |
| 101 | self.position.advance(self.string[match.start() : match.end()]) |
| 102 | return match.groups() |
| 103 | |
| 104 | |
| 105 | def decode_escapes(regex: Pattern[str], string: str) -> str: |
no outgoing calls
no test coverage detected
searching dependent graphs…