def concat(nfa1: NFA, nfa2: NFA): nfa = NFA(Alphabet({Automata.EPSILON})) equiv_states = {} for state in nfa1.states: equiv_states[state] = nfa.addState() for state in nfa2.states: equiv_states[state] = nfa.addState() for start_state in nfa1.start: nfa.start.add(equiv_states[start_state]) for final in nfa1.final: for start in nfa2.start: nfa.addTransition(equiv_states[final], equiv_states[start], NFA.EPSILON) for state in nfa1.states: for label in nfa.alphabet: for dest in nfa1.transitions[state][label]: nfa.addTransition(equiv_states[state], equiv_states[dest], label) for state in nfa2.states: for label in nfa.alphabet: for dest in nfa2.transitions[state][label]: nfa.addTransition(equiv_states[state], equiv_states[dest], label) for final in nfa2.final: nfa.final.add(equiv_states[final]) return nfa
def compile(db): state = {} res = NFA(-1) res.add_transition(-1, NFA.ANY, -1) for row in db: res.add_transition(-1, NFA.EPSILON, (0,row)) for i,v in enumerate(row.sig): v = (NFA.ANY,) if v is None else (chr(x) for x in v) [res.add_transition((i,row), x, (i+1,row)) for x in v] res.add_transition((i+1,row), NFA.ANY, (i+1,row)) res.add_final_state((i+1,row)) state.setdefault((i+1,row), []).append(row) return state,res
def automata_concatenation(a1, a2): c = {} l = 0 d1 = 0 d2 = a1.states + d1 u = a2.states + d2 for (A, b), O in a1.map.items(): c[A + d1, b] = {F + d1 for F in O} for (A, b), O in a2.map.items(): c[A + d2, b] = {F + d2 for F in O} for z in a1.finals: try: X = c[z + d1, ''] except D: X = c[z + d1, ''] = t() X.add(a2.start + d2) for z in a2.finals: try: X = c[z + d2, ''] except D: X = c[z + d2, ''] = t() X.add(u) J = a1.states + a2.states + 2 S = {u} return NFA(J, S, c, l)
def literal(literal: Literal): nfa = NFA(Alphabet({Automata.EPSILON})) start = nfa.addState() final = nfa.addState() nfa.start = {start} nfa.final = {final} for label in literal.alphabet: for start in nfa.start: for final in nfa.final: nfa.addTransition(start, final, label) return nfa
def automata_closure(a1): c = {} l = 0 d1 = 1 u = a1.states + d1 for (A, b), O in a1.map.items(): c[A + d1, b] = {F + d1 for F in O} c[l, ''] = [a1.start + d1, u] for z in a1.finals: try: X = c[z + d1, ''] except D: X = c[z + d1, ''] = t() X.add(u) X.add(a1.start + d1) J = a1.states + 2 S = {u} return NFA(J, S, c, l)
def build_automaton_regular_grammar(G): no_state = 0 states = {} finals_states = [] transitions = {} state_name = {} for non_term in G.nonTerminals: for prod in non_term.productions: left, right = prod try: state_left = states[left] except KeyError: state_left = states[left] = no_state state_name[no_state] = str(left) no_state += 1 l = len(right) if l == 1 or right == G.Epsilon: new_state = no_state state_name[no_state] = ' ' no_state += 1 finals_states.append(new_state) try: transitions[(state_left, str(right))].append(new_state) except KeyError: transitions[(state_left, str(right))] = [new_state] elif l == 2: nt = right._symbols[1] try: right_state = states[nt] except KeyError: right_state = states[nt] = no_state state_name[no_state] = str(nt) no_state += 1 try: transitions[(state_left, str(right._symbols[0]))].append(right_state) except KeyError: transitions[(state_left, str(right._symbols[0]))] = [right_state] nfa = NFA(no_state, finals_states, transitions, state_name, states[G.startSymbol]) dfa = nfa_to_dfa(nfa) return dfa
def automata_union(a1, a2): c = {} l = 0 d1 = 1 d2 = a1.states + d1 u = a2.states + d2 for (A, b), O in a1.map.items(): c[A + d1, b] = {F + d1 for F in O} for (A, b), O in a2.map.items(): c[A + d2, b] = {F + d2 for F in O} c[l, ''] = [a1.start + d1, a2.start + d2] for dx, S in a([d1, d2], [a1.finals, a2.finals]): for z in S: try: X = c[z + dx, ''] except D: X = c[z + dx, ''] = t() X.add(u) J = a1.states + a2.states + 2 S = {u} return NFA(J, S, c, l)
def __init__(self, states, finals, transitions, start=0): assert L(y(value, e) for value in transitions.values()) assert L(g(b) > 0 for A, b in transitions) transitions = {key: [value] for key, value in transitions.items()} NFA.__init__(self, states, finals, transitions, start) self.current = start
def evaluate(self): s = self.lex return NFA(states=2, finals=[1], transitions={(0, s): [1]})
def evaluate(self): return NFA(states=1, finals=[0], transitions={})
def star(nfa: NFA): new_start = nfa.addState() new_end = nfa.addState() for start in nfa.start: nfa.addTransition(new_start, start, NFA.EPSILON) for final in nfa.final: nfa.addTransition(final, new_end, NFA.EPSILON) for start in nfa.start: for final in nfa.final: nfa.addTransition(final, start, NFA.EPSILON) nfa.addTransition(new_start, new_end, NFA.EPSILON) nfa.start = [new_start] nfa.final = [new_end] return nfa
def emptyWord(): nfa = NFA(Alphabet()) nfa.start = {nfa.addState()} nfa.final = nfa.start.copy() return nfa
def union(nfa1: NFA, nfa2: NFA): nfa = NFA(Alphabet({Automata.EPSILON})) equiv_states = {} for state in nfa1.states: equiv_states[state] = nfa.addState() for state in nfa2.states: equiv_states[state] = nfa.addState() for state in nfa1.states: for label in nfa1.alphabet: for dest in nfa1.transitions[state][label]: nfa.addTransition(equiv_states[state], equiv_states[dest], label) for state in nfa2.states: for label in nfa2.alphabet: for dest in nfa2.transitions[state][label]: nfa.addTransition(equiv_states[state], equiv_states[dest], label) new_start = nfa.addState() new_end = nfa.addState() for start in nfa1.start: nfa.addTransition(new_start, equiv_states[start], NFA.EPSILON) for start in nfa2.start: nfa.addTransition(new_start, equiv_states[start], NFA.EPSILON) for final in nfa1.final: nfa.addTransition(equiv_states[final], new_end, NFA.EPSILON) for final in nfa2.final: nfa.addTransition(equiv_states[final], new_end, NFA.EPSILON) nfa.start = {new_start} nfa.final = {new_end} return nfa
def compile(db): state = {} res = NFA(-1) res.add_transition(-1, NFA.ANY, -1) for row in db: res.add_transition(-1, NFA.EPSILON, (0, row)) for i, v in enumerate(row.sig): v = (NFA.ANY, ) if v is None else (chr(x) for x in v) [res.add_transition((i, row), x, (i + 1, row)) for x in v] res.add_transition((i + 1, row), NFA.ANY, (i + 1, row)) res.add_final_state((i + 1, row)) state.setdefault((i + 1, row), []).append(row) return state, res