| OLD | NEW |
| 1 # Copyright 2013 the V8 project authors. All rights reserved. | 1 # Copyright 2013 the V8 project authors. All rights reserved. |
| 2 # Redistribution and use in source and binary forms, with or without | 2 # Redistribution and use in source and binary forms, with or without |
| 3 # modification, are permitted provided that the following conditions are | 3 # modification, are permitted provided that the following conditions are |
| 4 # met: | 4 # met: |
| 5 # | 5 # |
| 6 # * Redistributions of source code must retain the above copyright | 6 # * Redistributions of source code must retain the above copyright |
| 7 # notice, this list of conditions and the following disclaimer. | 7 # notice, this list of conditions and the following disclaimer. |
| 8 # * Redistributions in binary form must reproduce the above | 8 # * Redistributions in binary form must reproduce the above |
| 9 # copyright notice, this list of conditions and the following | 9 # copyright notice, this list of conditions and the following |
| 10 # disclaimer in the documentation and/or other materials provided | 10 # disclaimer in the documentation and/or other materials provided |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 self.__add_transition(key, end) | 86 self.__add_transition(key, end) |
| 87 if not self.__unclosed: | 87 if not self.__unclosed: |
| 88 self.add_epsilon_transition(end) | 88 self.add_epsilon_transition(end) |
| 89 self.__unclosed = None | 89 self.__unclosed = None |
| 90 | 90 |
| 91 def __matches(self, match_func, value): | 91 def __matches(self, match_func, value): |
| 92 f = lambda acc, (k, vs): acc | vs if match_func(k, value) else acc | 92 f = lambda acc, (k, vs): acc | vs if match_func(k, value) else acc |
| 93 return reduce(f, self.__transitions.items(), set()) | 93 return reduce(f, self.__transitions.items(), set()) |
| 94 | 94 |
| 95 def char_matches(self, value): | 95 def char_matches(self, value): |
| 96 return self.__matches((lambda k, v : k.matches_char(v)), value) | 96 return self.__matches(lambda k, v : k.matches_char(v), value) |
| 97 | 97 |
| 98 def key_matches(self, value): | 98 def key_matches(self, value): |
| 99 return self.__matches((lambda k, v : k.matches_key(v)), value) | 99 return self.__matches(lambda k, v : k.matches_key(v), value) |
| 100 | 100 |
| 101 @staticmethod | 101 @staticmethod |
| 102 def gather_transition_keys(state_set): | 102 def gather_transition_keys(state_set): |
| 103 f = lambda acc, state: acc | set(state.__transitions.keys()) | 103 f = lambda acc, state: acc | set(state.__transitions.keys()) |
| 104 return TransitionKey.merge_key_set(reduce(f, state_set, set())) | 104 return TransitionKey.disjoint_keys(reduce(f, state_set, set())) |
| 105 | 105 |
| 106 class NfaBuilder: | 106 class NfaBuilder: |
| 107 | 107 |
| 108 def __init__(self): | 108 def __init__(self): |
| 109 self.__operation_map = {} | 109 self.__operation_map = {} |
| 110 self.__members = getmembers(self) | 110 self.__members = getmembers(self) |
| 111 | 111 |
| 112 def __new_state(self): | 112 def __new_state(self): |
| 113 node_number = self.node_number | 113 node_number = self.node_number |
| 114 self.node_number = self.node_number + 1 | 114 self.node_number = self.node_number + 1 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 def __not_class(self, graph): | 162 def __not_class(self, graph): |
| 163 return self.__key_state(TransitionKey.character_class(True, graph[1])) | 163 return self.__key_state(TransitionKey.character_class(True, graph[1])) |
| 164 | 164 |
| 165 def __any(self, graph): | 165 def __any(self, graph): |
| 166 return self.__key_state(TransitionKey.any()) | 166 return self.__key_state(TransitionKey.any()) |
| 167 | 167 |
| 168 def __process(self, graph): | 168 def __process(self, graph): |
| 169 assert type(graph) == TupleType | 169 assert type(graph) == TupleType |
| 170 method = "_NfaBuilder__" + graph[0].lower() | 170 method = "_NfaBuilder__" + graph[0].lower() |
| 171 if not method in self.__operation_map: | 171 if not method in self.__operation_map: |
| 172 matches = filter((lambda (name, func): name == method), self.__members) | 172 matches = filter(lambda (name, func): name == method, self.__members) |
| 173 assert len(matches) == 1 | 173 assert len(matches) == 1 |
| 174 self.__operation_map[method] = matches[0][1] | 174 self.__operation_map[method] = matches[0][1] |
| 175 return self.__operation_map[method](graph) | 175 return self.__operation_map[method](graph) |
| 176 | 176 |
| 177 def __patch_ends(self, ends, new_end): | 177 def __patch_ends(self, ends, new_end): |
| 178 for end in ends: | 178 for end in ends: |
| 179 end.close(new_end) | 179 end.close(new_end) |
| 180 | 180 |
| 181 def nfa(self, graph): | 181 def nfa(self, graph): |
| 182 self.node_number = 0 | 182 self.node_number = 0 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 for c in string: | 246 for c in string: |
| 247 f = lambda acc, state: acc | state.char_matches(c) | 247 f = lambda acc, state: acc | state.char_matches(c) |
| 248 valid_states = Nfa.__close(reduce(f, valid_states, set())) | 248 valid_states = Nfa.__close(reduce(f, valid_states, set())) |
| 249 if not valid_states: | 249 if not valid_states: |
| 250 return False | 250 return False |
| 251 return self.__end in valid_states | 251 return self.__end in valid_states |
| 252 | 252 |
| 253 @staticmethod | 253 @staticmethod |
| 254 def __to_dfa(nfa_state_set, builder): | 254 def __to_dfa(nfa_state_set, builder): |
| 255 nfa_state_set = Nfa.__close(nfa_state_set) | 255 nfa_state_set = Nfa.__close(nfa_state_set) |
| 256 assert nfa_state_set |
| 256 name = str([x.node_number() for x in nfa_state_set]) | 257 name = str([x.node_number() for x in nfa_state_set]) |
| 257 (dfa_nodes, end_nodes, end_node) = builder | 258 (dfa_nodes, end_nodes, end_node) = builder |
| 258 if name in dfa_nodes: | 259 if name in dfa_nodes: |
| 259 return name | 260 return name |
| 260 dfa_node = {} | 261 dfa_node = {} |
| 261 dfa_nodes[name] = dfa_node | 262 dfa_nodes[name] = dfa_node |
| 262 for key in NfaState.gather_transition_keys(nfa_state_set): | 263 for key in NfaState.gather_transition_keys(nfa_state_set): |
| 263 f = lambda acc, state: acc | state.key_matches(key) | 264 f = lambda acc, state: acc | state.key_matches(key) |
| 264 dfa_node[key] = Nfa.__to_dfa(reduce(f, nfa_state_set, set()), builder) | 265 dfa_node[key] = Nfa.__to_dfa(reduce(f, nfa_state_set, set()), builder) |
| 265 if end_node in nfa_state_set: | 266 if end_node in nfa_state_set: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 292 digraph finite_state_machine { | 293 digraph finite_state_machine { |
| 293 rankdir=LR; | 294 rankdir=LR; |
| 294 node [shape = circle, style=filled, bgcolor=lightgrey]; S_%s | 295 node [shape = circle, style=filled, bgcolor=lightgrey]; S_%s |
| 295 node [shape = doublecircle, style=unfilled]; S_%s | 296 node [shape = doublecircle, style=unfilled]; S_%s |
| 296 node [shape = circle]; | 297 node [shape = circle]; |
| 297 %s | 298 %s |
| 298 } | 299 } |
| 299 ''' % (self.__start.node_number(), | 300 ''' % (self.__start.node_number(), |
| 300 self.__end.node_number(), | 301 self.__end.node_number(), |
| 301 "\n".join(node_content)) | 302 "\n".join(node_content)) |
| OLD | NEW |