def test_cnf(self): """ Tests the conversion to CNF form """ # pylint: disable=too-many-locals var_i = Variable("I") var_f = Variable("F") var_e = Variable("E") var_t = Variable("C#CNF#1") ter_a = Terminal("a") ter_b = Terminal("b") ter_0 = Terminal("0") ter_1 = Terminal("1") ter_par_open = Terminal("(") ter_par_close = Terminal(")") ter_mult = Terminal("*") ter_plus = Terminal("+") productions = { Production(var_i, [ter_a]), Production(var_i, [ter_b]), Production(var_i, [var_i, ter_a]), Production(var_i, [var_i, ter_b]), Production(var_i, [var_i, ter_0]), Production(var_i, [var_i, ter_1]), Production(var_f, [var_i]), Production(var_f, [ter_par_open, var_e, ter_par_close]), Production(var_t, [var_f]), Production(var_t, [var_t, ter_mult, var_f]), Production(var_e, [var_t]), Production(var_e, [var_e, ter_plus, var_t]) } cfg = CFG({var_i, var_f, var_e, var_t}, { ter_a, ter_b, ter_0, ter_1, ter_par_open, ter_par_close, ter_mult, ter_plus }, var_e, productions) new_cfg = cfg.to_normal_form() self.assertEqual(len(new_cfg.variables), 15) self.assertEqual(len(new_cfg.terminals), 8) self.assertEqual(len(new_cfg.productions), 41) self.assertFalse(cfg.is_empty()) new_cfg2 = cfg.to_normal_form() self.assertEqual(new_cfg, new_cfg2) cfg2 = CFG(start_symbol=var_e, productions={Production(var_e, [var_t])}) new_cfg = cfg2.to_normal_form() self.assertEqual(len(new_cfg.variables), 1) self.assertEqual(len(new_cfg.terminals), 0) self.assertEqual(len(new_cfg.productions), 0) self.assertTrue(cfg2.is_empty())
def test_intersection_with_epsilon(self): state0 = State(0) state1 = State(1) symb_a = Symbol("a") dfa = DeterministicFiniteAutomaton({state0, state1}, {symb_a}, start_state=state0, final_states={state1}) dfa.add_transition(state0, symb_a, state1) self.assertTrue(dfa.accepts([symb_a])) ter_a = Terminal("a") var_s = Variable("S") var_l = Variable("L") var_t = Variable("T") productions = { Production(var_s, [var_l, var_t]), Production(var_l, [Epsilon()]), Production(var_t, [ter_a]) } cfg = CFG(productions=productions, start_symbol=var_s) self.assertFalse(cfg.is_empty()) self.assertTrue(cfg.contains([ter_a])) cfg_temp = cfg.to_pda().to_cfg() self.assertFalse(cfg_temp.is_empty()) self.assertTrue(cfg_temp.contains([ter_a])) cfg_temp = cfg.to_pda().to_final_state().to_empty_stack().to_cfg() self.assertFalse(cfg_temp.is_empty()) self.assertTrue(cfg_temp.contains([ter_a])) cfg_i = cfg.intersection(dfa) self.assertFalse(cfg_i.is_empty())
def test_creation(self): """ Tests creatin of CFG """ variable0 = Variable(0) terminal0 = Terminal("a") prod0 = Production(variable0, [terminal0, Terminal("A"), Variable(1)]) cfg = CFG({variable0}, {terminal0}, variable0, {prod0}) self.assertIsNotNone(cfg) self.assertEqual(len(cfg.variables), 2) self.assertEqual(len(cfg.terminals), 2) self.assertEqual(len(cfg.productions), 1) self.assertTrue(cfg.is_empty()) cfg = CFG() self.assertIsNotNone(cfg) self.assertEqual(len(cfg.variables), 0) self.assertEqual(len(cfg.terminals), 0) self.assertEqual(len(cfg.productions), 0) self.assertTrue(cfg.is_empty())
def test_emptiness(self): """ Tests the emptiness of a CFG """ # pylint: disable=too-many-locals var_s = Variable("S") ter_a = Terminal("a") ter_b = Terminal("b") prod0 = Production(var_s, [ter_a, var_s, ter_b]) prod1 = Production(var_s, []) cfg = CFG({var_s}, {ter_a, ter_b}, var_s, {prod0, prod1}) self.assertFalse(cfg.is_empty())
def test_useless_removal(self): """ Test the removal of useless symbols """ var_a = Variable("A") var_b = Variable("B") ter_a = Terminal("a") ter_b = Terminal("b") start = Variable("S") prod0 = Production(start, [var_a, var_b]) prod1 = Production(start, [ter_a]) prod2 = Production(var_a, [ter_b]) cfg = CFG({var_a, var_b, start}, {ter_a, ter_b}, start, {prod0, prod1, prod2}) new_cfg = cfg.remove_useless_symbols() self.assertEqual(len(new_cfg.variables), 1) self.assertEqual(len(new_cfg.terminals), 1) self.assertEqual(len(new_cfg.productions), 1) self.assertFalse(cfg.is_empty())
def test_remove_epsilon(self): """ Tests the removal of epsilon """ var_a = Variable("A") var_b = Variable("B") ter_a = Terminal("a") ter_b = Terminal("b") start = Variable("S") prod0 = Production(start, [var_a, var_b]) prod1 = Production(var_a, [ter_a, var_a, var_a]) prod2 = Production(var_a, [Epsilon()]) prod3 = Production(var_b, [ter_b, var_b, var_b]) prod4 = Production(var_b, []) cfg = CFG({var_a, var_b, start}, {ter_a, ter_b}, start, {prod0, prod1, prod2, prod3, prod4}) new_cfg = cfg.remove_epsilon() self.assertEqual(len(new_cfg.variables), 3) self.assertEqual(len(new_cfg.terminals), 2) self.assertEqual(len(set(new_cfg.productions)), 9) self.assertEqual(len(new_cfg.get_nullable_symbols()), 0) self.assertFalse(cfg.is_empty())