Commit b966e26f authored by Kateřina Sloupová's avatar Kateřina Sloupová
Browse files

only backup, nothing good

parent 000fe7ef
Loading
Loading
Loading
Loading
Loading
+135 −108
Original line number Diff line number Diff line
from typing import List, Dict, Tuple, Optional
from typing import Set, List, Dict, Tuple, Optional
from enum import Enum
from copy import deepcopy

# TODO ask: out or in the class
#Rules = Dict[Nonterminal, Set[Tuple[Terminal, Optional[Nonterminal]]]]

# TODO Mypy typecheck

class Operation(Enum):
    Union = 1
    Intersection = 2


class Terminal:
    def __init__(self, name=str):
    def __init__(self, name: str):  # str = "a"):
        self.name = name

    def __eq__(self, object):
        if isinstance(object, Terminal):
            return object.name == self.name
        return False

    def __hash__(self):
        return hash(self.name)


class Nonterminal:
    def __init__(self, name=str):
    def __init__(self, name: str):
        self.name = name


class State:
    def __init__(self, name=str):
    def __init__(self, name: str):
        self.name = name


class REG:
    def __init__(self, nonterminals, terminals, rules, init):
        self.nonterminals = Set[Nonterminal]
        self.terminals = Set[Terminal]
        self.rules = Dict[Nonterminal, Set[Tuple[Terminal, Optional[Nonterminal]]]]
        self.init = Nonterminal
    Rules = Dict[Nonterminal, Set[Tuple[Terminal, Optional[Nonterminal]]]]

        
class DFA:
    def __init__(self, states, terminals, rules, init):
        self.states = Set[State]
        self.terminals = Set[Terminal]
        self.transition = Dict[Tuple[State, Terminal], State]
        self.init = State
        self.final = Set[State]
    def __init__(self, nonterminals: Set[Nonterminal], \
                 terminals: Set[Terminal], \
                 rules: Rules, \
                 init: Nonterminal):
        self.nonterminals = nonterminals
        self.terminals = terminals
        self.rules = rules
        self.init = init


class DFA:
    Transition = Dict[Tuple[State, Terminal], State]

    def __init__(self, states: Set[State], \
                 terminals: Set[Terminal], \
                 transition: Transition, \
                 init: State, \
                 final: Set[State]):
        self.states = states
        self.terminals = terminals
        self.transition = transition
        self.init = init
        self.final = final

    # def total(self) -> DFA:
    def total(self):
        total = Dict[Tuple[State, Terminal], State]
        hell = State("h")
        self.states.add(hell)
    
        for state in self.states:
            for terminal in self.terminals:
                if (state, term) in self.transition:
                    total[state, term] = self.transition[state, term]
        dfa = deepcopy(self)
        #total: Transition
        total = {}

        # better way?
        id = 0
        hell = State(str(id))
        while hell in dfa.states:
            id += 1
            hell.name = str(id)
        dfa.states.add(hell)
        print(dfa.states)

        for state in dfa.states:
            for terminal in dfa.terminals:
                if (state, terminal) in dfa.transition:
                    total[state, terminal] = dfa.transition[state, terminal]
                else:
                    total[state, term] = hell
                    total[state, terminal] = hell

        self.transition = total
        # TODO ask: or make/return copy of original DFA?
        dfa.transition = total
        return dfa

    # def complement(self) -> DFA:
    def complement(self):
        new_final = Set[State]
        for state in self.states:
            if state not in self.final:
        dfa = deepcopy(self)
        new_final: Set[State]
        for state in dfa.states:
            if state not in dfa.final:
                new_final.add(state)

        self.final = new_final
        # TODO ask: same as total
    
        
class NFA:
    def __init__(self, states, terminals, transition, init, final):
        self.states = Set[State]
        self.terminals = Set[Terminal]
        self.transition = Dict[Tuple[State, Terminal], Set[State]]
        self.init = State
        self.final = Set[State]
        
        dfa.final = new_final
        return dfa

# TODO ask: where to have this kind of functions?
# TODO ask: "union" & "intersection" like this?
def composition(dfa_1: DFA, dfa_2: DFA, operation: str) -> DFA:
    @staticmethod
    # def composition(dfa_1: DFA, dfa_2: DFA, operation: Operation) -> DFA:
    def composition(dfa_1, dfa_2, operation: Operation):
        dfa = DFA()

        # new states
@@ -89,9 +115,9 @@ def composition(dfa_1: DFA, dfa_2: DFA, operation: str) -> DFA:

                # new final
                if state_1 in dfa_1.final or state_2 in dfa_2.final:
                if operation == "union":
                    if operation == Operation.Union:
                        dfa.final.add(state)
                elif operation == "intersection" and \
                    elif operation == Operation.Intersection and \
                            state_1 in dfa_1.final and \
                            state_2 in dfa_2.final:
                        dfa.final.add(state)
@@ -105,25 +131,26 @@ def composition(dfa_1: DFA, dfa_2: DFA, operation: str) -> DFA:

        return dfa

    @staticmethod
    # def union(dfa_1: DFA, dfa_2: DFA) -> DFA:
    def union(dfa_1, dfa_2):
        composition(dfa_1, dfa_2, Union)

def test_dfa() -> DFA:
    dfa = DFA
    q_0 = State("q_0")
    q_1 = State("q_1")
    a = Terminal("a")
    dfa.init = q_0
    dfa.final = {q_0}
    dfa.terminals = {a}
    dfa.transition = dict()
    dfa.transition[q_0, a] = q_1
    dfa.transition[q_1, a] = q_1
    return dfa
    @staticmethod
    # def intersection(dfa_1: DFA, dfa_2: DFA) -> DFA:
    def intersection(dfa_1, dfa_2):
        composition(dfa_1, dfa_2, Intersection)


class NFA:
    def __init__(self, states: Set[State], \
                 terminals: Set[Terminal], \
                 transition: Dict[Tuple[State, Terminal], Set[State]], \
                 init: State, \
                 final: Set[State]):
        self.states = states
        self.terminals = terminal
        self.transition = transition
        self.init = init
        self.final = final
dfa = test_dfa()
print(len(dfa.transition))
dfa.total()
print(len(dfa.transition))
b = Terminal("b")
dfa.terminals.add(b)
dfa.total()
print(len(dfa.transition))
 No newline at end of file
+54 −22
Original line number Diff line number Diff line
from typing import List, Dict, Tuple, Optional
import re
import objects
from objects import REG, DFA


class Parser:
@@ -8,11 +8,10 @@ class Parser:
        pass

    # TODO ask: how should reg, dfa, ... look like?
test_reg = ((S,A,B,C),(a,b,c),P,S) /
             P={S->a|aA|b, /
    test_reg = "((S,A,B,C),(a,b,c),P,S) \
             P={S->a|aA|b, \
             A->c}"


    def reg_to_str(self, reg: REG) -> str:
        out = "(("
        for neterminal in reg.neterminals:
@@ -25,11 +24,11 @@ test_reg = ((S,A,B,C),(a,b,c),P,S) /
                out.append(",")
            out.append(terminal)
        out.append(",P," + reg.init + ")\nP=")
        out.append(rules_to_str(self, reg.rules)
        out.append(rules_to_str(self, reg.rules))
        return out

        
        # Rules = Dict[Nonterminal, List[Tuple[Terminal, Optional[Nonterminal]]]]

    # TODO ask: from objects import rules (as type)?
    def rules_to_str(self, rules):
        out = "{"
@@ -49,11 +48,44 @@ test_reg = ((S,A,B,C),(a,b,c),P,S) /

            return (out[:len(out) - 2] + "}")

    #    def str_to_reg(self, source: str) -> REG:
    #        re.match(...((nt),(t),P,S)\n rest

    test_dfa = "(0,a)=1\n(1,a)=0\nF={1}"

    def dfa_to_str(self, dfa: DFA, full=False) -> str:

        # full - verbose description of DFA - only for development, dismiss later
        
    def str_to_reg(self, source: str) -> REG:
        re.match(...((nt),(t),P,S)\n rest
        states = "{"
        for state in dfa.states:
                states += state.name + ","
        states = states[:-1] + "}"
            
        terminals = "{"
        for state in dfa.terminals:
                terminals += state.name + ","
        terminals = terminals[:-1] + "}"

        transition = "{"
        for key, state_2 in dfa.transition.items():
            state_1, terminal = key
            transition += "(" + state_1.name + "," + terminal.name + ")=" + state_2.name + "\n"
        transition = transition[:-1] + "}"

        init = dfa.init.name

        final = "F={"
        for state in dfa.final:
            final += state.name + ","
        final = final[:-1] + "}"

        if full:
            return "DFA = (" + states + "," + terminals + ",d," + \
                  init + "," + final + ")\n" + "d = " + transition

        else:
            return transition + "\n" + final

# all: string <-> formal object
# reg

test.py

0 → 100644
+39 −0
Original line number Diff line number Diff line
from parser import Parser
from objects import Terminal, State, DFA


def test_dfa():
    q_0 = State("q_0")
    q_1 = State("q_1")
    a = Terminal("a")
    states = {q_0, q_1}
    init = q_0
    final = {q_0}
    terminals = {a}
    transition = dict()
    transition[q_0, a] = q_1
    transition[q_1, a] = q_1
    dfa = DFA(states, terminals, transition, init, final)
    print(dfa)
    return dfa


def main():
    dfa = test_dfa()
    parser = Parser()

    # test: dfa_to_str
    print(parser.dfa_to_str(dfa))
    print()
    print(parser.dfa_to_str(dfa, True))

    # test: add terminal, make total
    #print(len(dfa.transition))
    b = Terminal("b")
    dfa.terminals.add(b)
    tot_dfa = dfa.total()
    #print(len(dfa.transition))
    print(parser.dfa_to_str(tot_dfa, True))


main()
 No newline at end of file