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

add first attempt of objects and parser

parent 5b96da8e
Loading
Loading
Loading
Loading
Loading

objects.py

0 → 100644
+129 −0
Original line number Diff line number Diff line
from typing import List, Dict, Tuple, Optional

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


class Terminal:
    def __init__(self, name=str):
        self.name = name
        
        
class Nonterminal:
    def __init__(self, name=str):
        self.name = name
        
        
class State:
    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
        
        
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 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]
                else:
                    total[state, term] = hell

        self.transition = total
        # TODO ask: or make/return copy of original DFA?
        
    def complement(self):
        new_final = Set[State]
        for state in self.states:
            if state not in self.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]
        

# 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:
    dfa = DFA()
    
    # new states
    for state_1 in dfa_1.states:
        for state_2 in dfa_2.states:
            state = State(state_1.name + "_" + state_2.name)
            dfa.states.add(state)
            
            # TODO not sure with not dfa.init
            # new init
            if not dfa.init and state_1 == dfa_1.init \
                            and state_2 == dfa_2.init:
                dfa.init = state
            
            # new final
            if state_1 in dfa_1.final or state_2 in dfa_2.final:
                if operation == "union":
                    dfa.final.add(state)
                elif operation == "intersection" and \
                          state_1 in dfa_1.final and \
                          state_2 in dfa_2.final:
                    dfa.final.add(state)
                    
    # new terminals
    dfa.terminals.add(dfa_1.terminals)
    dfa.terminals.add(dfa_2.terminals)
    # ATTENTION: terminals may differ -> make total at the end?
    
    # TODO new transition
    
    return dfa
    
    
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
    
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

parser.py

0 → 100644
+63 −0
Original line number Diff line number Diff line
from typing import List, Dict, Tuple, Optional
import re
import objects


class Parser:
    def __init__(self):
        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, /
             A->c}"


    def reg_to_str(self, reg: REG) -> str:
        out = "(("
        for neterminal in reg.neterminals:
            if next:#TODO
                out.append(",")
            out.append(neterminal)
        out.append("),(")
        for terminal in reg.terminals:
            if next:#TODO
                out.append(",")
            out.append(terminal)
        out.append(",P," + reg.init + ")\nP=")
        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 = "{"
        for rule in reg.rules:
            nonterminal, rewrite = rule
            if len(rewrite) == 0:
                continue
                
            out.append(nonterminal + "->")
            for variant in rewrite:
                for character in variant:
                    out.append(variant)
                if next: #TODO
                    out.append("|")
                else:
                    out.append(",\n")
                    
            return (out[:len(out)-2] + "}")
            
            
    def str_to_reg(self, source: str) -> REG:
        re.match(...((nt),(t),P,S)\n rest
    
    

# all: string <-> formal object
# reg
# dfa
# nfa
# pda
# cfg
 No newline at end of file