def test_derive(a, b): # Just some basic tests because this is mainly a regex thing. assert a.derive("a") == epsilon({"a", "b"}) assert a.derive("b") == null({"a", "b"}) try: a.derive("c") assert False except KeyError: assert True assert (a * 3).derive("a") == a * 2 assert (a.star() - epsilon({"a", "b"})).derive("a") == a.star()
def fsm(self, alphabet=None): from greenery.fsm import epsilon if alphabet is None: alphabet = self.alphabet() # worked example: (min, max) = (5, 7) or (5, inf) # (mandatory, optional) = (5, 2) or (5, inf) unit = self.multiplicand.fsm(alphabet) # accepts e.g. "ab" # accepts "ababababab" mandatory = unit * self.multiplier.mandatory.v # unlimited additional copies if self.multiplier.optional == inf: optional = unit.star() # accepts "(ab)*" else: optional = epsilon(alphabet) | unit # accepts "(ab)?" optional *= self.multiplier.optional.v # accepts "(ab)?(ab)?" return mandatory + optional
def fsm(self, alphabet=None): from greenery.fsm import epsilon if alphabet is None: alphabet = self.alphabet() # start with a component accepting only the empty string fsm1 = epsilon(alphabet) for m in self.mults: fsm1 += m.fsm(alphabet) return fsm1
def test_concatenation_aa(a): concAA = a + a assert not concAA.accepts("") assert not concAA.accepts("a") assert concAA.accepts("aa") assert not concAA.accepts("aaa") concAA = epsilon({"a", "b"}) + a + a assert not concAA.accepts("") assert not concAA.accepts("a") assert concAA.accepts("aa") assert not concAA.accepts("aaa")
def test_optional_mul(a, b): unit = a + b # accepts "ab" optional = (epsilon(a.alphabet) | unit) # accepts "(ab)? assert optional.accepts([]) assert not optional.accepts(["a"]) assert not optional.accepts(["b"]) assert optional.accepts(["a", "b"]) assert not optional.accepts(["a", "a"]) optional = optional * 2 # accepts "(ab)?(ab)?" assert optional.accepts([]) assert not optional.accepts(["a"]) assert not optional.accepts(["b"]) assert not optional.accepts(["a", "a"]) assert optional.accepts(["a", "b"]) assert not optional.accepts(["b", "a"]) assert not optional.accepts(["b", "b"]) assert not optional.accepts(["a", "a", "a"]) assert optional.accepts(["a", "b", "a", "b"])
def test_concatenate_bug(a): # This exposes a defect in fsm.concatenate. assert fsm.concatenate(a, epsilon({"a"}), a).accepts("aa") assert fsm.concatenate(a, epsilon({"a"}), epsilon({"a"}), a).accepts("aa")
def test_builtins(): assert not null("a").accepts("a") assert epsilon("a").accepts("") assert not epsilon("a").accepts("a")
def test_reverse_epsilon(): # epsilon reversed is epsilon assert reversed(epsilon("a")).accepts("")
def to_fsm(self, alphabet=None, prefix_postfix=None, flags=None) -> FSM: if alphabet is None: alphabet = self.alphabet return epsilon(alphabet)