hurl/bin/docs/parser.py

74 lines
2.3 KiB
Python

from typing import Callable
class Parser:
"""Base class for text parser.
This class provides method for a text parser. This can be used as an instance
or be extended for a custom parser.
Attributes:
buffer: the text buffer to parse.
offset: offset of the current parsing position within the buffer.
"""
buffer: str
offset: int
def __init__(self, buffer: str) -> None:
self.buffer = buffer
self.offset = 0
def read(self, count: int = 1) -> str:
"""Return count characters from the buffer."""
if self.left() < count:
return ""
ret = self.buffer[self.offset : self.offset + count]
self.offset += count
return ret
def read_while(self, f: Callable[[str], bool]) -> str:
"""Return characters from the buffer while the current character meet a criteria."""
offset = self.offset
while self.left() > 0:
c = self.peek()
if f(c):
_ = self.read()
else:
break
return self.buffer[offset : self.offset]
def read_while_prev(self, f: Callable[[str, str], bool]) -> str:
"""Return characters from the buffer while the current and previous character meet a criteria."""
offset = self.offset
while self.left() > 0:
c = self.peek()
prev = self.buffer[self.offset - 1]
if f(c, prev):
_ = self.read()
else:
break
return self.buffer[offset : self.offset]
def peek(self, count: int = 1) -> str:
"""Return count characters from the buffer, without modifying the parsing offset."""
if self.left() < count:
return ""
return self.buffer[self.offset : self.offset + count]
def peek_while(self, f) -> str:
"""Return characters from the buffer while the current character meet a criteria, without modifying the
parsing offset."""
offset = self.offset
while offset < len(self.buffer):
c = self.buffer[offset]
if f(c):
offset += 1
else:
break
return self.buffer[self.offset : offset]
def left(self) -> int:
"""Return the number of characters left to read."""
return len(self.buffer) - self.offset