| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 if not self.transistions_match( | 100 if not self.transistions_match( |
| 101 encoding, key, incoming_state, state): | 101 encoding, key, incoming_state, state): |
| 102 continue | 102 continue |
| 103 # this transition can be removed | 103 # this transition can be removed |
| 104 replacements[incoming_state][key] = None | 104 replacements[incoming_state][key] = None |
| 105 if not replacements: | 105 if not replacements: |
| 106 return | 106 return |
| 107 # perform replacement | 107 # perform replacement |
| 108 states = {} | 108 states = {} |
| 109 name = lambda state : str(state.node_number()) | 109 name = lambda state : str(state.node_number()) |
| 110 counters = {'removals' : 0, 'gotos' : 0} | 110 counters = { |
| 111 'removals' : 0, |
| 112 'goto_start' : 0, |
| 113 'store_token_and_goto' : 0, |
| 114 'store_harmony_token_and_goto' : 0, |
| 115 } |
| 111 store_states = set([]) | 116 store_states = set([]) |
| 112 # generate a store action to replace an existing action | 117 # generate a store action to replace an existing action |
| 113 def replacement_action(old_action, match_action): | 118 def replacement_action(old_action, transition_state): |
| 114 assert not old_action.entry_action() | 119 assert not old_action.entry_action() |
| 115 assert old_action.match_action() | 120 assert old_action.match_action() |
| 121 state_id = name(transition_state) |
| 116 if old_action.match_action()[0] == 'token': | 122 if old_action.match_action()[0] == 'token': |
| 117 entry_action = ('store_token', old_action.match_action()[1]) | 123 old_token = old_action.match_action()[1] |
| 124 if (transition_state.action().match_action()[0] == 'token' and |
| 125 transition_state.action().match_action()[1] == old_token): |
| 126 # no need to store token |
| 127 match_action = ('goto_start', (state_id,)) |
| 128 counters['goto_start'] += 1 |
| 129 else: |
| 130 counters['store_token_and_goto'] += 1 |
| 131 match_action = ('store_token_and_goto', (old_token, state_id)) |
| 118 elif old_action.match_action()[0] == 'harmony_token': | 132 elif old_action.match_action()[0] == 'harmony_token': |
| 119 entry_action = ('store_harmony_token', old_action.match_action()[1]) | 133 match_action = ('store_harmony_token_and_goto', |
| 134 (old_action.match_action()[1][0], |
| 135 old_action.match_action()[1][1], |
| 136 old_action.match_action()[1][2], |
| 137 state_id)) |
| 138 counters['store_harmony_token_and_goto'] += 1 |
| 120 else: | 139 else: |
| 121 raise Exception(old_action.match_action()) | 140 raise Exception(old_action.match_action()) |
| 122 return Action(entry_action, match_action, old_action.precedence()) | 141 return Action(None, match_action, old_action.precedence()) |
| 123 # map the old state to the new state, with fewer transitions and | 142 # map the old state to the new state, with fewer transitions and |
| 124 # goto actions | 143 # goto actions |
| 125 def replace_state(state, acc): | 144 def replace_state(state, acc): |
| 126 new_state = { | 145 new_state = { |
| 127 'transitions' : {}, | 146 'transitions' : {}, |
| 128 'terminal' : state in self.__dfa.terminal_set(), | 147 'terminal' : state in self.__dfa.terminal_set(), |
| 129 'action' : state.action(), | 148 'action' : state.action(), |
| 130 } | 149 } |
| 131 states[name(state)] = new_state | 150 states[name(state)] = new_state |
| 132 state_replacements = replacements[state] if state in replacements else {} | 151 state_replacements = replacements[state] if state in replacements else {} |
| 133 for transition_key, transition_state in state.transitions().items(): | 152 for transition_key, transition_state in state.transitions().items(): |
| 134 if not transition_key in state_replacements: | 153 if not transition_key in state_replacements: |
| 135 new_state['transitions'][transition_key] = name(transition_state) | 154 new_state['transitions'][transition_key] = name(transition_state) |
| 136 continue | 155 continue |
| 137 replacement = state_replacements[transition_key] | 156 replacement = state_replacements[transition_key] |
| 138 del state_replacements[transition_key] | 157 del state_replacements[transition_key] |
| 139 # just drop the transition | 158 # just drop the transition |
| 140 if replacement == None: | 159 if replacement == None: |
| 141 counters['removals'] += 1 | 160 counters['removals'] += 1 |
| 142 continue | 161 continue |
| 162 assert replacement == transition_state |
| 143 # do goto replacement | 163 # do goto replacement |
| 144 counters['gotos'] += 1 | 164 new_state['action'] = replacement_action(state.action(), replacement) |
| 145 match_action = ('goto', name(transition_state)) | |
| 146 new_state['action'] = replacement_action(state.action(), match_action) | |
| 147 # will need to patch up transition_state | 165 # will need to patch up transition_state |
| 148 store_states.add(name(transition_state)) | 166 store_states.add(name(transition_state)) |
| 149 assert not state_replacements | 167 assert not state_replacements |
| 150 self.__dfa.visit_all_states(replace_state) | 168 self.__dfa.visit_all_states(replace_state) |
| 151 # now patch up all states with stores | 169 # now patch up all states with stores |
| 152 for state_id in store_states: | 170 for state_id in store_states: |
| 153 old_action = states[state_id]['action'] | 171 old_action = states[state_id]['action'] |
| 172 assert not old_action.entry_action() |
| 173 assert old_action.match_action()[0] == 'token', 'unimplemented' |
| 174 entry_action = ('store_token', old_action.match_action()[1]) |
| 154 match_action = ('do_stored_token', state_id) | 175 match_action = ('do_stored_token', state_id) |
| 155 states[state_id]['action'] = replacement_action(old_action, match_action) | 176 precedence = old_action.precedence() |
| 177 states[state_id]['action'] = Action( |
| 178 entry_action, match_action, precedence) |
| 156 start_name = name(self.__dfa.start_state()) | 179 start_name = name(self.__dfa.start_state()) |
| 157 if self.__log: | 180 if self.__log: |
| 158 print 'gotos inserted %s' % counters['gotos'] | 181 print 'goto_start inserted %s' % counters['goto_start'] |
| 182 print 'store_token_and_goto inserted %s' % ( |
| 183 counters['store_token_and_goto']) |
| 184 print 'store_harmony_token_and_goto %s' % ( |
| 185 counters['store_harmony_token_and_goto']) |
| 159 print 'transitions removed %s' % counters['removals'] | 186 print 'transitions removed %s' % counters['removals'] |
| 160 print 'do_stored_token actions added %s' % len(store_states) | 187 print 'do_stored_token actions added %s' % len(store_states) |
| 161 self.__dfa = Dfa(self.__dfa.encoding(), start_name, states) | 188 self.__dfa = Dfa(self.__dfa.encoding(), start_name, states) |
| 162 | 189 |
| 163 @staticmethod | 190 @staticmethod |
| 164 def optimize(dfa, log): | 191 def optimize(dfa, log): |
| 165 optimizer = DfaOptimizer(dfa, log) | 192 optimizer = DfaOptimizer(dfa, log) |
| 166 optimizer.replace_tokens_with_gotos() | 193 optimizer.replace_tokens_with_gotos() |
| 167 return optimizer.__dfa | 194 return optimizer.__dfa |
| OLD | NEW |