class NFA: regexp = None m = 0 def __init__(self, regexp): self.regexp = regexp self.m = len(regexp) self.graph = Digraph(self.m + 1) ops = [] for i in range(0, self.m): lp = i if regexp[i] == '(' or regexp[i] == '|': ops += [i] elif regexp[i] == ')': or_ = ops.pop() if regexp[or_] == '|': lp = ops.pop() self.graph.addEdge(lp, or_ + 1) self.graph.addEdge(or_, i) elif regexp[or_] == '(': lp = or_ else: assert False if i < self.m - 1 and regexp[i + 1] == '*': self.graph.addEdge(lp, i + 1) self.graph.addEdge(i + 1, lp) if regexp[i] == '(' or regexp[i] == '*' or regexp[i] == ')': self.graph.addEdge(i, i + 1) if len(ops) != 0: raise ValueError("Invalid regular expression") def recognizes(self, txt): dfs = DirectedDFS(self.graph, [0]) pc = [] for v in range(0, self.graph.Vertex()): if dfs.marked[v]: pc += [v] for i in range(0, len(txt)): if txt[i] == '*' or txt[i] == '|' or txt[i] == '(' or txt[i] == ')': raise ValueError("text contains the metacharacter %s" % (txt[i])) match = [] for v in pc: if v == self.m: continue if self.regexp[v] == txt[i] or self.regexp[v] == '.': match += [v + 1] dfs = DirectedDFS(self.graph, match) pc = [] for v in range(0, self.graph.Vertex()): if dfs.marked[v]: pc += [v] if len(pc) == 0: return False for v in pc: if v == self.m: return True return False
class SymbolDigraph: def __init__(self, filename, delimiter): self.st = dict() self.keys = dict() delimiter = None myin = In(filename, delimiter) while myin.hasNextLine(): a = myin.readLine().split(delimiter) for i in range(0, len(a)): if self.st.get(a[i]) == None: self.st[a[i]] = len(self.st) for name in self.st.keys(): self.keys[self.st[name]] = name self.graph = Digraph(len(self.st.keys())) myin = In(filename, '\n') while myin.hasNextLine(): a = myin.readLine().split(' ') v = self.st.get(a[0]) for i in range(1, len(a)): w = self.st.get(a[i]) self.graph.addEdge(v, w) def contains(self, s): if self.st.get(s) == None: return False else: return True def index(self, s): return self.st.get(s) def indexOf(self, s): return self.get(s) def name(self, v): self.validateVertex(v) return self.keys[v] def nameOf(self, v): self.validateVertex(v) return self.keys[v] def G(self): return self.graph def digraph(self): return self.graph def validateVertex(self, v): Ver = self.graph.Vertex() if v < 0 or v >= Ver: raise ("vertex %d is not between 0 and %d " % (v, Ver - 1))
return self.id[v] def check(self, G): pass def validateVertex(self, v): V = len(self.marked) if v < 0 or v >= V: raise ("vertex %d is not between 0 and %d" % (v, V - 1)) if __name__ == '__main__': myin = In(sys.argv[1], None) G = Digraph(myin) scc = KosarajuSharirSCC(G) m = scc.mcount() print("%d strong components" % m) components = [None] * m for i in range(0, m): components[i] = [] for v in range(0, G.Vertex()): components[scc.vid(v)].append(v) s = "" for i in range(0, m): for v in components[i]: s += "%d " % v s += '\n' print(s)