import typing
[docs]
class Rule:
"""
A class that is used to create and modify the :class:`DCFG`.
The API uses :class:`str` for symbols.
:class:`Rule` is immutable, hashable and has its equivalence implemented.
.. warning:: Passing a :class:`str` as :attr:`rhs` is undefined behavior -- strings
are iterable, so the constructor would silently produce a per-character
rule. Pass a tuple, list, or other iterable of symbol strings.
"""
[docs]
def __init__(self, lhs: str, rhs: typing.Iterable[str]) -> None:
self.__lhs = lhs
self.__rhs = tuple(rhs)
@property
def lhs(self) -> str:
"""
:getter: Left hand side.
:type: str
"""
return self.__lhs
@property
def rhs(self) -> typing.Tuple[str, ...]:
"""
:getter: Right hand side.
:type: tuple[str]
"""
return self.__rhs
[docs]
def __repr__(self) -> str:
return "Rule({} => {})".format(repr(self.lhs), " ".join([repr(symbol) for symbol in self.rhs]))
[docs]
def __eq__(self, other: object) -> bool:
if not isinstance(other, Rule):
return NotImplemented
return self.lhs == other.lhs and self.rhs == other.rhs
[docs]
def __hash__(self) -> int:
return hash((self.lhs, self.rhs))