def test_creation(self): # S -> a S b | a b enfa = Regex("a S b | a b").to_epsilon_nfa() dfa = enfa.minimize() box = Box(dfa, Symbol("S")) rsa_1 = RecursiveAutomaton({Symbol("S")}, Symbol("S"), {box}) self.assertEqual(rsa_1.get_number_of_boxes(), 1) self.assertEqual(box.is_equivalent_to(rsa_1.get_box(Symbol("S"))), True) self.assertEqual(rsa_1.labels, {Symbol("S")}) self.assertEqual(rsa_1.initial_label, Symbol("S")) rsa_2 = RecursiveAutomaton() rsa_2.add_box(box) rsa_2.change_initial_label(Symbol("S")) self.assertEqual(rsa_2.is_equivalent_to(rsa_1), True) # Checking to add a start label rsa_3 = RecursiveAutomaton(set(), Symbol("S"), {box}) self.assertEqual(rsa_3.labels, {Symbol("S")}) try: rsa_4 = RecursiveAutomaton({Symbol("S"), Symbol("v")}, Symbol("S"), {box}) except ValueError: self.assertEqual(True, True)
def from_cfg(cls, cfg: CFG): """ Create a recursive automaton from context-free grammar Parameters ----------- cfg : :class:`~pyformlang.cfg.CFG` The context-free grammar Returns ----------- rsa : :class:`~pyformlang.rsa.RecursiveAutomaton` The new recursive automaton built from context-free grammar """ initial_label = to_symbol(cfg.start_symbol) grammar_in_true_format = remove_repetition_of_nonterminals_from_productions( cfg.to_text()) boxes = set() labels = set() notation_for_epsilon = Epsilon().to_text() for production in grammar_in_true_format.splitlines(): head, body = production.split(" -> ") labels.add(to_symbol(head)) if body == "": body = notation_for_epsilon boxes.add( Box(Regex(body).to_epsilon_nfa().minimize(), to_symbol(head))) return RecursiveAutomaton(labels, initial_label, boxes)
def test_from_regex(self): # S -> a* rsa_2 = RecursiveAutomaton.from_regex(Regex("a*"), Symbol("S")) enfa = Regex("a*").to_epsilon_nfa() dfa = enfa.minimize() box = Box(dfa, Symbol("S")) rsa_1 = RecursiveAutomaton({Symbol("S")}, Symbol("S"), {box}) self.assertEqual(rsa_2, rsa_1)
def test_from_cfg(self): # g1: S -> a S b | a b rsa1_g1 = RecursiveAutomaton.from_cfg( CFG.from_text("S -> a S b | a b")) rsa2_g1 = RecursiveAutomaton.from_regex(Regex("a S b | a b"), Symbol("S")) self.assertEqual(rsa1_g1, rsa2_g1) # g2: S -> a V b # V -> c S d | c d rsa1_g2 = RecursiveAutomaton.from_cfg( CFG.from_text("S -> a V b\nV -> c S d | c d")) self.assertEqual(rsa1_g2.get_number_of_boxes(), 2) self.assertEqual(rsa1_g2.labels, {Symbol("S"), Symbol("V")}) dfa_S = Regex("a V b").to_epsilon_nfa().minimize() self.assertEqual(rsa1_g2.get_box(Symbol("S")), Box(dfa_S, Symbol("S"))) dfa_V = Regex("c S d | c d").to_epsilon_nfa().minimize() self.assertEqual(rsa1_g2.get_box(Symbol("V")), Box(dfa_V, Symbol("V")))
def from_regex(cls, regex: str, initial_label: Symbol): """ Create a recursive automaton from regular expression Parameters ----------- regex : str The regular expression initial_label : :class:`~pyformlang.finite_automaton.Symbol` A initial label for the recursive automaton Returns ----------- rsa : :class:`~pyformlang.rsa.RecursiveAutomaton` The new recursive automaton """ initial_label = Symbol(initial_label) box = Box(Regex(regex).to_epsilon_nfa(), initial_label) return RecursiveAutomaton({initial_label}, initial_label, {box})
def test_add_box(self): rsa_1 = RecursiveAutomaton.from_regex(Regex("a* b*"), Symbol("S")) new_box = Box(Regex("a*").to_epsilon_nfa().minimize(), Symbol("S")) rsa_1.add_box(new_box) self.assertEqual(new_box.dfa, rsa_1.get_box(Symbol("S")).dfa) self.assertEqual(rsa_1.labels, {Symbol("S")})