| 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 20 matching lines...) Expand all Loading... |
| 31 | 31 |
| 32 class DfaState(AutomatonState): | 32 class DfaState(AutomatonState): |
| 33 | 33 |
| 34 def __init__(self, name, action, transitions): | 34 def __init__(self, name, action, transitions): |
| 35 super(DfaState, self).__init__() | 35 super(DfaState, self).__init__() |
| 36 self.__name = name | 36 self.__name = name |
| 37 self.__transitions = transitions | 37 self.__transitions = transitions |
| 38 self.__action = action | 38 self.__action = action |
| 39 assert isinstance(action, Action) | 39 assert isinstance(action, Action) |
| 40 | 40 |
| 41 def sort_transitions(self): |
| 42 self.__transitions = sorted(self.__transitions, |
| 43 cmp = lambda (k1, v1), (k2, v2): cmp(k1, k2)) |
| 44 |
| 41 def name(self): | 45 def name(self): |
| 42 return self.__name | 46 return self.__name |
| 43 | 47 |
| 44 def action(self): | 48 def action(self): |
| 45 return self.__action | 49 return self.__action |
| 46 | 50 |
| 47 def transition_count(self): | 51 def omega_transition(self): |
| 48 return len(self.__transitions) | 52 if (self.__transitions and |
| 53 self.__transitions[-1][0] == TransitionKey.omega()): |
| 54 return self.__transitions[-1][1] |
| 55 return None |
| 49 | 56 |
| 50 def omega_transition(self): | 57 def match_action(self): |
| 51 if TransitionKey.omega() in self.__transitions: | 58 '''returns an action if this state's omega transition terminates |
| 52 return self.__transitions[TransitionKey.omega()] | 59 immediately and has an action''' |
| 53 return None | 60 omega_chain = list(self.omega_chain_iter()) |
| 61 if len(omega_chain) == 1 and omega_chain[0][1] == 0: |
| 62 return omega_chain[0][0].action() |
| 63 return Action.empty_action() |
| 64 |
| 65 def omega_chain_iter(self): |
| 66 state = self |
| 67 while True: |
| 68 state = state.omega_transition() |
| 69 if not state: |
| 70 return |
| 71 transistion_count = len(state.__transitions) |
| 72 yield (state, transistion_count) |
| 73 if not (transistion_count == 0 or |
| 74 (transistion_count == 1 and state.omega_transition())): |
| 75 return |
| 54 | 76 |
| 55 def epsilon_closure_iter(self): | 77 def epsilon_closure_iter(self): |
| 56 return iter([]) | 78 return iter([]) |
| 57 | 79 |
| 58 def transition_state_for_key(self, value): | 80 def transition_state_for_key(self, value): |
| 59 matches = list(self.transition_state_iter_for_key(value)) | 81 matches = list(self.transition_state_iter_for_key(value)) |
| 60 assert len(matches) <= 1 | 82 assert len(matches) <= 1 |
| 61 return matches[0] if matches else None | 83 return matches[0] if matches else None |
| 62 | 84 |
| 63 def key_state_iter( | 85 def key_state_iter( |
| 64 self, | 86 self, |
| 65 key_filter = lambda x: True, | 87 key_filter = lambda x: True, |
| 66 state_filter = lambda x: True, | 88 state_filter = lambda x: True, |
| 67 match_func = lambda x, y: True, | 89 match_func = lambda x, y: True, |
| 68 yield_func = lambda x, y: (x, y)): | 90 yield_func = lambda x, y: (x, y)): |
| 69 for key, state in self.__transitions.items(): | 91 for (key, state) in self.__transitions: |
| 70 if key_filter(key) and state_filter(state) and match_func(key, state): | 92 if key_filter(key) and state_filter(state) and match_func(key, state): |
| 71 yield yield_func(key, state) | 93 yield yield_func(key, state) |
| 72 | 94 |
| 73 class Dfa(Automaton): | 95 class Dfa(Automaton): |
| 74 | 96 |
| 75 @staticmethod | 97 @staticmethod |
| 76 def __add_transition(transitions, key, state): | 98 def __add_transition(transitions, key, state): |
| 77 assert key != None | 99 assert key != None and key != TransitionKey.epsilon() |
| 78 assert not key == TransitionKey.epsilon() | 100 transitions.append((key, state)) |
| 79 assert not transitions.has_key(key) | |
| 80 transitions[key] = state | |
| 81 | 101 |
| 82 def __init__(self, encoding, start_name, mapping): | 102 def __init__(self, encoding, start_name, mapping): |
| 83 super(Dfa, self).__init__(encoding) | 103 super(Dfa, self).__init__(encoding) |
| 84 self.__terminal_set = set() | 104 self.__terminal_set = set() |
| 85 name_map = {} | 105 name_map = {} |
| 86 for name, node_data in mapping.items(): | 106 for name, node_data in mapping.items(): |
| 87 transitions = {} | 107 transitions = [] |
| 88 node = DfaState(name, node_data['action'], transitions) | 108 node = DfaState(name, node_data['action'], transitions) |
| 89 name_map[name] = (node, transitions) | 109 name_map[name] = (node, transitions) |
| 90 if node_data['terminal']: | 110 if node_data['terminal']: |
| 91 self.__terminal_set.add(node) | 111 self.__terminal_set.add(node) |
| 92 all_keys = [] | 112 all_keys = [] |
| 93 for name, node_data in mapping.items(): | 113 for name, node_data in mapping.items(): |
| 94 (node, transitions) = name_map[name] | 114 (node, transitions) = name_map[name] |
| 95 inversion = {} | 115 inversion = {} |
| 116 omega_state = None |
| 96 for key, state in node_data['transitions'].items(): | 117 for key, state in node_data['transitions'].items(): |
| 118 if key == TransitionKey.omega(): |
| 119 omega_state = name_map[state][0] |
| 97 if not state in inversion: | 120 if not state in inversion: |
| 98 inversion[state] = [] | 121 inversion[state] = [] |
| 99 inversion[state].append(key) | 122 inversion[state].append(key) |
| 100 for state, keys in inversion.items(): | 123 for state, keys in inversion.items(): |
| 101 all_keys += keys | 124 all_keys += keys |
| 102 merged_key = TransitionKey.merged_key(encoding, keys) | 125 merged_key = TransitionKey.merged_key(encoding, keys) |
| 103 self.__add_transition(transitions, merged_key, name_map[state][0]) | 126 self.__add_transition(transitions, merged_key, name_map[state][0]) |
| 127 node.sort_transitions() |
| 128 assert node.omega_transition() == omega_state |
| 104 self.__start = name_map[start_name][0] | 129 self.__start = name_map[start_name][0] |
| 105 self.__node_count = len(mapping) | 130 self.__node_count = len(mapping) |
| 106 self.__disjoint_keys = sorted( | 131 self.__disjoint_keys = sorted( |
| 107 TransitionKey.disjoint_keys(encoding, all_keys)) | 132 TransitionKey.disjoint_keys(encoding, all_keys)) |
| 108 self.__verify() | 133 self.__verify() |
| 109 | 134 |
| 110 def __verify(self): | 135 def __verify(self): |
| 111 assert self.__terminal_set | 136 assert self.__terminal_set |
| 112 state_count = self.visit_all_states(lambda state, count: count + 1, 0) | 137 state_count = self.visit_all_states(lambda state, count: count + 1, 0) |
| 113 assert self.__node_count == state_count | 138 assert self.__node_count == state_count |
| (...skipping 12 matching lines...) Expand all Loading... |
| 126 return iter(self.__disjoint_keys) | 151 return iter(self.__disjoint_keys) |
| 127 | 152 |
| 128 def node_count(self): | 153 def node_count(self): |
| 129 return self.__node_count | 154 return self.__node_count |
| 130 | 155 |
| 131 def start_state(self): | 156 def start_state(self): |
| 132 return self.__start | 157 return self.__start |
| 133 | 158 |
| 134 def terminal_set(self): | 159 def terminal_set(self): |
| 135 return set(self.__terminal_set) | 160 return set(self.__terminal_set) |
| OLD | NEW |