Verified Commit 713b35a7 authored by Vladimír Štill's avatar Vladimír Štill
Browse files

test: Import tests for CFG

parent 5ed47498
Loading
Loading
Loading
Loading

test_cfl_cfg.py

0 → 100644
+93 −0
Original line number Diff line number Diff line
from common import Nonterminal, Terminal
import cfl
from copy import deepcopy

S = Nonterminal("S")
A = Nonterminal("A")
B = Nonterminal("B")
C = Nonterminal("C")
a = Terminal("a")
b = Terminal("b")

Rules = cfl.CFG.Rules

rules0: Rules = dict()
g0 = cfl.CFG({A}, {a, b}, rules0, A)

rules1: Rules = {A: {(a,), (a, A), (b, B), (b,)},
                 B: {(b,), (b, B)}}
g1 = cfl.CFG({A, B}, {a, b}, rules1, A)

rules2: Rules = {A: {(a,), (a, A), (b, B)},
                 B: {(b, B), ()}}
g2 = cfl.CFG({A, B}, {a, b}, rules2, A)


def test_empty():
    assert g0.is_empty()


def test_basics():
    assert g1.init == A
    assert g1.terminals == {a, b}
    assert g1.nonterminals == {A, B}
    assert g1.rules == rules1
    collected_prods = set(g1.productions())
    assert collected_prods == {(src, dst) for src, prods in rules1.items()
                               for dst in prods}


def test_generates():
    def go(g):
        assert g.generates("a")
        assert g.generates("b")
        assert g.generates("aa")
        assert g.generates("ab")
        assert g.generates("abbb")
        assert g.generates("aabbb")
        assert not g.generates("")
        assert not g.generates("ba")

    go(g1)
    go(g2)


def test_remove_eps():
    g = g2.epsilon_normal_form()
    assert g.init == g1.init
    assert g.terminals == g1.terminals
    assert g.nonterminals == g1.nonterminals
    assert g.rules == g1.rules


def test_equal():
    R = Nonterminal("R")
    P = Nonterminal("P")
    u, d, p, v, z = tuple(Terminal(x) for x in "udpvz")
    rules = {S: {(u, R, S), ()},
             R: {(p, P), (d,), (u, R, R), ()},
             P: {(z,), (v, R)}}
    g = cfl.CFG({S, R, P}, {u, d, p, v, z}, rules, S)
    assert g.generates("")
    assert g.generates("uu")
    assert g.generates("uudu")
    assert g.generates("uudpvd")
    assert g.generates("uduududd")
    assert g.generates("uupvpzudd")
    assert not g.generates("d")
    assert not g.generates("up")
    assert not g.generates("duu")
    assert not g.generates("uv")
    assert not g.generates("udz")
    assert not g.generates("upuv")

    assert cfl.CFG.is_equivalent_test(g, g, max_cmp_len=16)

    rules_e0 = {S: {(u, R), ()},
                R: {(p, P), (d,), (u, R, R), ()},
                P: {(z,), (v, R)}}
    ge0 = cfl.CFG({S, R, P}, {u, d, p, v, z}, rules_e0, S)
    r = cfl.CFG.is_equivalent_test(g, ge0, max_cmp_len=16)
    assert not r
    print(r.__dict__)