def register(cls, symbol, **kwargs): """ Register/update a token class in the symbol table. :param symbol: The identifier symbol for a new class or an existent token class. :param kwargs: Optional attributes/methods for the token class. :return: A token class. """ try: try: if ' ' in symbol: raise ValueError("%r: a symbol can't contain whitespaces" % symbol) except TypeError: assert isinstance(symbol, type) and issubclass(symbol, Token), \ "A %r subclass requested, not %r." % (Token, symbol) symbol, token_class = symbol.symbol, symbol assert symbol in cls.symbol_table and cls.symbol_table[symbol] is token_class, \ "Token class %r is not registered." % token_class else: token_class = cls.symbol_table[symbol] except KeyError: # Register a new symbol and create a new custom class. The new class # name is registered at parser class's module level. if symbol not in cls.SYMBOLS: raise NameError('%r is not a symbol of the parser %r.' % (symbol, cls)) kwargs['symbol'] = symbol label = kwargs.get('label', 'symbol') if isinstance(label, tuple): label = kwargs['label'] = MultiLabel(*label) token_class_name = "_{}{}".format( symbol_to_classname(symbol), str(label).title().replace(' ', '') ) token_class_bases = kwargs.get('bases', (cls.token_base_class,)) kwargs.update({ '__module__': cls.__module__, '__qualname__': token_class_name, '__return__': None }) token_class = ABCMeta(token_class_name, token_class_bases, kwargs) cls.symbol_table[symbol] = token_class MutableSequence.register(token_class) setattr(sys.modules[cls.__module__], token_class_name, token_class) else: for key, value in kwargs.items(): if key == 'lbp' and value > token_class.lbp: token_class.lbp = value elif key == 'rbp' and value > token_class.rbp: token_class.rbp = value elif callable(value): setattr(token_class, key, value) return token_class
def schema_constructor(self, atomic_type_name: str, bp: int = 90) \ -> Type[XPathFunction]: """Registers a token class for a schema atomic type constructor function.""" if atomic_type_name in (XSD_ANY_ATOMIC_TYPE, XSD_NOTATION): raise xpath_error('XPST0080') def nud_(self_: XPathFunction) -> XPathFunction: self_.parser.advance('(') self_[0:] = self_.parser.expression(5), self_.parser.advance(')') try: self_.value = self_.evaluate() # Static context evaluation except MissingContextError: self_.value = None return self_ def evaluate_(self_: XPathFunction, context: Optional[XPathContext] = None) \ -> Union[List[None], AtomicValueType]: arg = self_.get_argument(context) if arg is None or self_.parser.schema is None: return [] value = self_.string_value(arg) try: return self_.parser.schema.cast_as(value, atomic_type_name) except (TypeError, ValueError) as err: raise self_.error('FORG0001', err) symbol = get_prefixed_name(atomic_type_name, self.namespaces) token_class_name = "_%sConstructorFunction" % symbol.replace(':', '_') kwargs = { 'symbol': symbol, 'nargs': 1, 'label': 'constructor function', 'pattern': r'\b%s(?=\s*\(|\s*\(\:.*\:\)\()' % symbol, 'lbp': bp, 'rbp': bp, 'nud': nud_, 'evaluate': evaluate_, '__module__': self.__module__, '__qualname__': token_class_name, '__return__': None } token_class = cast( Type[XPathFunction], ABCMeta(token_class_name, (XPathFunction, ), kwargs)) MutableSequence.register(token_class) self.symbol_table[symbol] = token_class return token_class
def schema_constructor(self, atomic_type, bp=90): """Registers a token class for a schema atomic type constructor function.""" if atomic_type in {XSD_ANY_ATOMIC_TYPE, XSD_NOTATION}: raise xpath_error('XPST0080') def nud_(self_): self_.parser.advance('(') self_[0:] = self_.parser.expression(5), self_.parser.advance(')') try: self_.value = self_.evaluate() # Static context evaluation except MissingContextError: self_.value = None return self_ def evaluate_(self_, context=None): arg = self_.get_argument(context) if arg is None: return [] value = self_.string_value(arg) try: return self_.parser.schema.cast_as(value, atomic_type) except (TypeError, ValueError) as err: raise self_.error('FORG0001', err) symbol = get_prefixed_name(atomic_type, self.namespaces) token_class_name = str("_%s_constructor_token" % symbol.replace(':', '_')) kwargs = { 'symbol': symbol, 'label': 'constructor function', 'pattern': r'\b%s(?=\s*\(|\s*\(\:.*\:\)\()' % symbol, 'lbp': bp, 'rbp': bp, 'nud': nud_, 'evaluate': evaluate_, '__module__': self.__module__, '__qualname__': token_class_name, '__return__': None } token_class = ABCMeta(token_class_name, (self.token_base_class, ), kwargs) MutableSequence.register(token_class) self.symbol_table[symbol] = token_class return token_class
def __jclass_init__(self): Sequence.register(self) MutableSequence.register(self)
""" Helper classmethod to construct a ``ParseResults`` from a ``dict``, preserving the name-value relations as results names. If an optional ``name`` argument is given, a nested ``ParseResults`` will be returned. """ def is_iterable(obj): try: iter(obj) except Exception: return False else: return not isinstance(obj, str_type) ret = cls([]) for k, v in other.items(): if isinstance(v, Mapping): ret += cls.from_dict(v, name=k) else: ret += cls([v], name=k, asList=is_iterable(v)) if name is not None: ret = cls([ret], name=name) return ret asList = as_list asDict = as_dict getName = get_name MutableMapping.register(ParseResults) MutableSequence.register(ParseResults)
def extend(self, values): end = len(self._items) self[end:end] = values pop = MutableSequence.pop remove = MutableSequence.remove __iadd__ = MutableSequence.__iadd__ # convenience def clear(self): del self[:] MutableSequence.register(List) class Selection(List): """Set of items with the additional notion of a cursor to the least recently *active* element. Each item can occur only once in the set. Note that the inherited ``List`` methods and signals can be used to listen for selection changes, and to query or delete items. However, for *inserting* or *modifying* elements, only use the methods defined in the ``Selection`` class can be used to ensure that items stay unique. """ def __init__(self): super().__init__()
def register(cls, symbol, **kwargs): """ Register/update a token class in the symbol table. :param symbol: The identifier symbol for a new class or an existent token class. :param kwargs: Optional attributes/methods for the token class. :return: A token class. """ def symbol_escape(s): s = re.escape(s) s.replace(r'\ ', r'\s+') if s.isalpha(): s = r'\b%s\b(?![\-\.])' % s elif s[-2:] == r'\(': s = r'%s\s*%s' % (s[:-2], s[-2:]) elif s[-4:] == r'\:\:': s = r'%s\s*%s' % (s[:-4], s[-4:]) return s try: try: if ' ' in symbol: raise ValueError( "%r: a symbol can't contains whitespaces." % symbol) except TypeError: assert isinstance(symbol, type) and issubclass(symbol, Token), \ "A %r subclass requested, not %r." % (Token, symbol) symbol, token_class = symbol.symbol, symbol assert symbol in cls.symbol_table and cls.symbol_table[symbol] is token_class, \ "Token class %r is not registered." % token_class else: token_class = cls.symbol_table[symbol] except KeyError: # Register a new symbol and create a new custom class. The new class # name is registered at parser class's module level. if symbol not in cls.SYMBOLS: raise NameError('%r is not a symbol of the parser %r.' % (symbol, cls)) kwargs['symbol'] = symbol if 'pattern' not in kwargs: pattern = symbol_escape( symbol) if len(symbol) > 1 else re.escape(symbol) kwargs['pattern'] = pattern label = kwargs.get('label', 'symbol') if isinstance(label, tuple): label = kwargs['label'] = MultiLabel(*label) token_class_name = "_{}_{}_token".format( symbol_to_identifier(symbol), str(label).replace(' ', '_')) token_class_bases = (getattr(cls, 'token_base_class', object), ) kwargs.update({ '__module__': cls.__module__, '__qualname__': token_class_name, '__return__': None }) token_class = ABCMeta(token_class_name, token_class_bases, kwargs) cls.symbol_table[symbol] = token_class MutableSequence.register(token_class) setattr(sys.modules[cls.__module__], token_class_name, token_class) else: for key, value in kwargs.items(): if key == 'lbp' and value > token_class.lbp: token_class.lbp = value elif key == 'rbp' and value > token_class.rbp: token_class.rbp = value elif callable(value): setattr(token_class, key, value) return token_class
@staticmethod def _c_one_lsb(index: int, stop: int = 0) -> _Gen: """ Consuming set bits starting from LSB.""" while index > stop: yield index index &= index - 1 @staticmethod def _c_zero_lsb(index: int, start: int = 2) -> _Gen: """ Yields powers of two that perfectly divide index. Consuming unset bits starting from LSB. """ while index & 1 == 0: yield start // 2 start <<= 1 index >>= 1 @staticmethod def _nmlz_index(index: int, length: int) -> int: """ Normalize index, bringing it in [0, len(self)), IndexError is raised if index is out of bounds. """ index = index + length if index < 0 else index if index >= length or length == 0: raise IndexError("Index out of range.") return index # Register as virtual subclass. MutableSequence.register(BIT)
return getattr(self, '_{}'.format(idx)) def __repr__(self): with stringify_context(self) as nested: cls = type(self).__qualname__ if nested: return "@{}".format(get_short_id(self)) else: return "{}@{}({})".format( cls, get_short_id(self), repr(list(self)), ) MutableSequence.register(ManagedList) # ------------- TEST ------------------- class Test(Managed): def init(self): self.a = 1 self.a = 2 self.node = self._resmngr.new(Node, 123) self.more = self._resmngr.new_list([ self._resmngr.new(Node, 100), self._resmngr.new(Node, 200), ])