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 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