builtup4/bu4/parsing/parser.py
2021-09-08 13:49:09 +03:00

49 lines
1.5 KiB
Python

# Copyright (c) PARRRATE T&V 2021. All rights reserved.
from io import BytesIO
from typing import Iterable, Type, TypeVar
from bu4.parsing.abstractparser import AbstractParser
from bu4.parsing.extensions.abstractextension import AbstractExtension
from bu4.parsing.extensions.extension import Extension
from bu4.parsing.states.parsingread import ParsingRead
__all__ = ('Parser',)
from bu4.transform.states.transformstate import TransformState
from bu4.transform.transform import transform
T = TypeVar('T')
class Parser(AbstractParser[T]):
def __init__(self, source: bytes, extensions: Iterable[Type[Extension[T]]]):
self.__source = BytesIO(source)
self.__extensions: dict[int, Extension[T]] = {}
for extension in extensions:
if extension.code in self.__extensions:
raise ValueError('code overload')
self.__extensions[extension.code] = extension(self)
def read(self) -> int:
bytes_ = self.__source.read(1)
return bytes_[0] if bytes_ else 0
def parse_name(self) -> bytes:
s = BytesIO()
while True:
c = self.read()
if not c:
return s.getvalue()
s.write(bytes([c]))
def extension_for(self, code: int) -> AbstractExtension[T]:
extension = self.__extensions.get(code)
if extension is None:
raise ValueError(f'unknown control: {hex(code)}')
return extension
def parse(self) -> TransformState[T]:
return ParsingRead(self)