Source code for paxter.core.scope_pattern

"""
Utility class for opened and closed pattern of the same scope:
brace pattern for `FragmentList`, quoted pattern for `Text`,
and bar pattern for `PaxterPhrase`.
"""
import re
from dataclasses import dataclass
from typing import Pattern

from paxter.core.lexers import LEXER

__all__ = ['ScopePattern', 'EMPTY_SCOPE_PATTERN', 'GLOBAL_SCOPE_PATTERN']

ALLOWED_OPENED_PATTERN_RE = re.compile(r'[#<]*[{"|]')
OPENED_TO_CLOSED_TRANS = str.maketrans(r'#<{"|', r'#>}"|')


[docs]@dataclass class ScopePattern: """ Data regarding the opened pattern and the closed pattern of one particular scope. """ #: The opening pattern enclosing the scope opening: str #: The closing pattern enclosing the scope closing: str = None def __post_init__(self): if self.closing is None: self.closing = self.flip_pattern(self.opening) @staticmethod def flip_pattern(opened: str) -> str: """ Flips the given opened (i.e. left) pattern into the corresponding closed (i.e. right) pattern. For example, the opened pattern `"<##<{"` should be flipped into the closed pattern `"}>##>". """ if not ALLOWED_OPENED_PATTERN_RE.fullmatch(opened): raise RuntimeError("something went horribly wrong") # pragma: no cover return opened.translate(OPENED_TO_CLOSED_TRANS)[::-1] @property def non_rec_break_re(self) -> Pattern[str]: """ Compiles a regular expression lexer to non-greedily match some text which is then followed by the given closed (i.e. right) pattern. """ return LEXER.non_rec_break_re(self.closing) @property def rec_break_re(self) -> Pattern[str]: """ Compiles a regular expression lexer to non-greedily match some text which is then followed by either the @-command switch symbol or the given closed (i.e. right) pattern. """ return LEXER.rec_break_re(self.closing)
class GlobalScopePattern(ScopePattern): """ Specialized scope pattern just for global-level fragment list. """ def __init__(self): super().__init__(opening='', closing='') @property def non_rec_break_re(self) -> Pattern[str]: """ Compiles a regular expression lexer to non-greedily match some text which is then followed by the given closed (i.e. right) pattern. """ raise AttributeError @property def rec_break_re(self) -> Pattern[str]: """ Compiles a regular expression lexer to non-greedily match some text which is then followed by either the @-command switch symbol or the given closed (i.e. right) pattern. """ return LEXER.global_break_re EMPTY_SCOPE_PATTERN = ScopePattern(opening='', closing='') GLOBAL_SCOPE_PATTERN = GlobalScopePattern()