def plus_nfa(self): start_status = Status() end_status = Status() end_status.accept = True nfa = self.nfa_stack.pop() nfa.end.accept = False nfa.end.epsilon.append(nfa.start) start_status.epsilon.append(nfa.start) nfa.end.epsilon.append(end_status) self.nfa_stack.append(NFA(start_status, end_status))
def bar_nfa(self): nfa_last = self.nfa_stack.pop() nfa_first = self.nfa_stack.pop() start_status = Status() end_status = Status() end_status.accept = True start_status.epsilon.append(nfa_first.start) start_status.epsilon.append(nfa_last.start) nfa_first.end.epsilon.append(end_status) nfa_last.end.epsilon.append(end_status) nfa_first.end.accept = False nfa_last.end.accept = False nfa = NFA(start_status, end_status) self.nfa_stack.append(nfa)
def char_nfa(self, token): start_status = Status() end_status = Status() start_status.translate(token.value, end_status) end_status.accept = True nfa = NFA(start_status, end_status) self.nfa_stack.append(nfa)
def simplify(self): # reset status counter Status.count = 0 new_start = Status() new_start.accept = self.start.accept simplified_dfa = DFA(new_start) status_mapping = {self.start: new_start} work_list = [self.start] while work_list: status = work_list.pop() new_status = status_mapping[status] if status not in self.table: # this status gos no where continue for k, v in self.table[status].items(): if v not in status_mapping: sub_status = Status() sub_status.accept = v.accept status_mapping.update({v: sub_status}) work_list.append(v) else: sub_status = status_mapping[v] simplified_dfa.translate(new_status, k, sub_status) return simplified_dfa
def reverse(self): # reset Status count Status.count = 0 end_status = Status() end_status.accept = True accept_status_list = [] status_list = {self.dfa.start: end_status} work_list = [self.dfa.start] while work_list: status = work_list.pop() new_status = status_list[status] if status not in self.dfa.table: # this status gos no where continue for k, v in self.dfa.table[status].items(): sub_status = None if v not in status_list: sub_status = Status() if v.accept: accept_status_list.append(sub_status) status_list.update({v: sub_status}) work_list.append(v) else: sub_status = status_list[v] sub_status.translate(k, new_status) start_status = Status() start_status.epsilon = accept_status_list return NFA(start_status, end_status)