| 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 12 matching lines...) Expand all Loading... |
| 23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 from transition_keys import TransitionKey | 28 from transition_keys import TransitionKey |
| 29 from automaton import * | 29 from automaton import * |
| 30 | 30 |
| 31 class NfaState(AutomatonState): | 31 class NfaState(AutomatonState): |
| 32 | 32 |
| 33 def __init__(self, node_number): | 33 def __init__(self): |
| 34 super(NfaState, self).__init__(node_number) | 34 super(NfaState, self).__init__() |
| 35 self.__transitions = {} | 35 self.__transitions = {} |
| 36 self.__unclosed = set() | 36 self.__unclosed = set() |
| 37 self.__epsilon_closure = None | 37 self.__epsilon_closure = None |
| 38 self.__action = None | 38 self.__action = None |
| 39 | 39 |
| 40 def transitions_to_multiple_states(self): | 40 def transitions_to_multiple_states(self): |
| 41 return True | 41 return True |
| 42 | 42 |
| 43 def epsilon_closure(self): | 43 def epsilon_closure(self): |
| 44 return self.__epsilon_closure | 44 return self.__epsilon_closure |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 valid_states = Nfa.__close(transitions) | 143 valid_states = Nfa.__close(transitions) |
| 144 return self.__end in valid_states | 144 return self.__end in valid_states |
| 145 | 145 |
| 146 @staticmethod | 146 @staticmethod |
| 147 def __gather_transition_keys(state_set): | 147 def __gather_transition_keys(state_set): |
| 148 keys = set(chain(*map(lambda state: state.key_iter(), state_set))) | 148 keys = set(chain(*map(lambda state: state.key_iter(), state_set))) |
| 149 keys.discard(TransitionKey.epsilon()) | 149 keys.discard(TransitionKey.epsilon()) |
| 150 return TransitionKey.disjoint_keys(keys) | 150 return TransitionKey.disjoint_keys(keys) |
| 151 | 151 |
| 152 @staticmethod | 152 @staticmethod |
| 153 def __gather_actions(states): |
| 154 action = None |
| 155 for state in states: |
| 156 if not state.action(): |
| 157 continue |
| 158 if not action: |
| 159 action = state.action() |
| 160 continue |
| 161 if state.action().precedence() == action.precedence(): |
| 162 assert state.action() == action |
| 163 elif state.action().precedence() < action.precedence(): |
| 164 action = state.action() |
| 165 return action |
| 166 |
| 167 @staticmethod |
| 153 def __to_dfa(nfa_state_set, dfa_nodes, end_node): | 168 def __to_dfa(nfa_state_set, dfa_nodes, end_node): |
| 154 nfa_state_set = Nfa.__close(nfa_state_set) | 169 nfa_state_set = Nfa.__close(nfa_state_set) |
| 155 assert nfa_state_set | 170 assert nfa_state_set |
| 156 name = ".".join(str(x.node_number()) for x in sorted(nfa_state_set)) | 171 name = ".".join(str(x.node_number()) for x in sorted(nfa_state_set)) |
| 157 if name in dfa_nodes: | 172 if name in dfa_nodes: |
| 158 return name | 173 return name |
| 159 def gather_actions(states): | |
| 160 actions = set() | |
| 161 for state in states: | |
| 162 if state.action(): | |
| 163 actions.add(state.action()) | |
| 164 actions = list(actions) | |
| 165 actions.sort() | |
| 166 return actions | |
| 167 dfa_nodes[name] = { | 174 dfa_nodes[name] = { |
| 168 'transitions': {}, | 175 'transitions': {}, |
| 169 'terminal': end_node in nfa_state_set, | 176 'terminal': end_node in nfa_state_set, |
| 170 'actions' : gather_actions(nfa_state_set)} | 177 'action' : Nfa.__gather_actions(nfa_state_set)} |
| 171 for key in Nfa.__gather_transition_keys(nfa_state_set): | 178 for key in Nfa.__gather_transition_keys(nfa_state_set): |
| 172 match_states = set() | 179 match_states = set() |
| 173 f = lambda acc, state: acc | state.key_matches(key) | 180 f = lambda acc, state: acc | state.key_matches(key) |
| 174 for state in reduce(f, nfa_state_set, set()): | 181 for state in reduce(f, nfa_state_set, set()): |
| 175 match_states.add(state) | 182 match_states.add(state) |
| 176 transition_state = Nfa.__to_dfa(match_states, dfa_nodes, end_node) | 183 transition_state = Nfa.__to_dfa(match_states, dfa_nodes, end_node) |
| 177 dfa_nodes[name]['transitions'][key] = transition_state | 184 dfa_nodes[name]['transitions'][key] = transition_state |
| 178 return name | 185 return name |
| 179 | 186 |
| 180 def compute_dfa(self): | 187 def compute_dfa(self): |
| 181 dfa_nodes = {} | 188 dfa_nodes = {} |
| 182 start_name = self.__to_dfa(set([self.__start]), dfa_nodes, self.__end) | 189 start_name = self.__to_dfa(set([self.__start]), dfa_nodes, self.__end) |
| 183 return (start_name, dfa_nodes) | 190 return (start_name, dfa_nodes) |
| OLD | NEW |