Mercurial > hg > Members > shinya > pyrect
diff pyrect/regexp/nfa.py @ 98:4d498b002de5
refactor for data-structure (dict -> Transition).
author | Ryoma SHINYA <shinya@firefly.cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 12 Dec 2010 23:04:31 +0900 |
parents | 19a88707bd29 |
children | 2632b963e441 |
line wrap: on
line diff
--- a/pyrect/regexp/nfa.py Sun Dec 12 19:02:37 2010 +0900 +++ b/pyrect/regexp/nfa.py Sun Dec 12 23:04:31 2010 +0900 @@ -3,16 +3,20 @@ import curses.ascii as ascii import copy import collections -from pyrect.regexp.fa import FA +from pyrect.regexp.fa import FA, Transition class NFAFragment(object): def __init__(self): self.start = None # integer self.accepts = set() # frozenset - self.map = dict() # transition, char or special -> frozenset([states]) + self.transition = Transition() # transition, char or special -> frozenset([states]) def connect(self, from_, char, to): - slot = self.map.setdefault((from_, char), set()) + if self.transition[from_, char]: + slot = self.transition[from_, char] + else: + slot = set() + self.transition[from_, char] = slot slot.add(to) def accept_to(self, from_, char): @@ -26,46 +30,44 @@ def new_skelton(self): # copy fragment (self), and it return newFrag = NFAFragment(); - newFrag.map = copy.deepcopy(self.map) + newFrag.transition = copy.deepcopy(self.transition) return newFrag def __or__(self, frag): newFrag = self.new_skelton() - for k, v in frag.map.iteritems(): - newFrag.map[k] = v.copy() + for k, v in frag.transition.iterstates(): + newFrag.transition[k] = copy.deepcopy(v) return newFrag def __str__(self): return ("NFA: delta -> %s, start -> %s, accepts -> %s" % - (self.map, self.start, self.accepts)) + (self.transition, self.start, self.accepts)) def build(self): - map_ = self.map - def transition(state, char): - return frozenset(map_.get((state, char), [])) - states = set() - for (s, _) in self.map.iterkeys(): + for s in self.transition.iterkeys(): states.add(s) return NFA( - transition, + self.transition, self.start, self.accepts, - self.map, sorted(states) ) class NFA(FA): - def epsilon_expand(self, set_): - que = set(set_) + def epsilon_expand(self, states): + if not isinstance(states, set) and \ + not isinstance(states, list): + states = set([states]) + states = copy.deepcopy(states) done = set() - while que: - stat = que.pop() - nexts = self.transition(stat, "") + while states: + stat = states.pop() done.add(stat) - for nextStat in nexts: - if not nextStat in done: que.add(nextStat) + if self.transition[stat, ""] != None: + for n in self.transition[stat, ""]: + if not n in done: states.add(n) return frozenset(done) class SuffixNFA(NFA): @@ -73,40 +75,36 @@ self.start = nfa.start self.accepts = copy.deepcopy(nfa.accepts) self.states = copy.deepcopy(nfa.states) - self.map = self.nfa_map(nfa) + self.transition = self.nfa_trans(nfa) start = set(self.states)-set([self.start]) if self.map.has_key((self.start, '')): self.map[(self.start, '')].add(start) else: self.map[(self.start, '')] = start - def nfa_map(self, fa): + def nfa_trans(self, fa): if type(fa) == NFA: - return copy.deepcopy(fa.map) - nmap = dict() - for k, v in fa.map.items(): - nmap[k] = set([v]) - return nmap - - def transition(self, state, char): - return frozenset(self.map.get((state, char), [])) + return copy.deepcopy(fa.transition) + ntrans = dict() + for k, v in fa.map.itertrans(): + ntrans[k] = set([v]) + return ntrans class SuffixTrieNFA(NFA): def __init__(self, dfa): self.start = dfa.start self.pdfa = dfa - self.map = dict() self.states = copy.deepcopy(dfa.states) self.acceptable = collections.defaultdict(set) self.accepts = copy.deepcopy(set(dfa.accepts)) states = [self.start] + list(set(self.states)-set((self.start,))) - self.make_trie_map(states) + self.make_trie_trans(states) - def make_trie_map(self, states): + def make_trie_trans(self, states): add_states = set() offset = [x * len(states) for x in range(len(states))] for s, ind in zip(states, offset): - for (s_, i), n in self.pdfa.map.iteritems(): + for (s_, i), n in self.pdfa.trans.itertrans(): sind = s_ + ind nind = n + ind add_states.add((sind, nind)) @@ -120,7 +118,4 @@ starts.add(self.start + i + offset[i]) self.states = list(add_states) - self.map[(self.start, '')] = starts - - def transition(self, state, char): - return frozenset(self.map.get((state, char), [])) + self.trans[(self.start, '')] = starts