mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-12-24 11:32:00 +03:00
74 lines
2.3 KiB
Python
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
|