| 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 def __unique_key(self, name): | 146 def __unique_key(self, name): |
| 147 return self.__key_state(TransitionKey.unique(name)) | 147 return self.__key_state(TransitionKey.unique(name)) |
| 148 | 148 |
| 149 def __entry_action(self, action, precedence, subtree): | 149 def __entry_action(self, action, precedence, subtree): |
| 150 (start, ends) = self.__process(subtree) | 150 (start, ends) = self.__process(subtree) |
| 151 node = self.__new_state() | 151 node = self.__new_state() |
| 152 node.set_action(Action(action, precedence)) | 152 node.set_action(Action(action, precedence)) |
| 153 self.__patch_ends(ends, node) | 153 self.__patch_ends(ends, node) |
| 154 return (start, [node]) | 154 return (start, [node]) |
| 155 | 155 |
| 156 def __match_action(self, action, precedence, subtree): | 156 def __build_match_node(self, action): |
| 157 (start, ends) = self.__process(subtree) | |
| 158 node = self.__new_state() | 157 node = self.__new_state() |
| 159 node.set_action(Action(action, precedence)) | 158 node.set_action(action) |
| 160 # Force all match actions to be terminal. | 159 # Force all match actions to be terminal. |
| 161 node.close(self.__global_end) | 160 node.close(self.__global_end) |
| 162 # patch via a match edge into existing graph | 161 # patch via a match edge into existing graph |
| 163 match_node = self.__new_state() | 162 match_node = self.__new_state() |
| 164 match_node.add_transition(TransitionKey.omega(), node) | 163 match_node.add_transition(TransitionKey.omega(), node) |
| 164 return match_node |
| 165 |
| 166 def __match_action(self, action, precedence, subtree): |
| 167 (start, ends) = self.__process(subtree) |
| 168 match_node = self.__build_match_node(Action(action, precedence)) |
| 165 self.__patch_ends(ends, match_node) | 169 self.__patch_ends(ends, match_node) |
| 166 return (start, [match_node]) | 170 return (start, [match_node]) |
| 167 | 171 |
| 168 def __continue(self, subtree, depth): | 172 def __continue(self, subtree, depth): |
| 169 'add an epsilon transitions to the start node of the current subtree' | 173 'add an epsilon transitions to the start node of the current subtree' |
| 170 (start, ends) = self.__process(subtree) | 174 (start, ends) = self.__process(subtree) |
| 171 index = -1 - min(int(depth), len(self.__states) - 1) | 175 index = -1 - min(int(depth), len(self.__states) - 1) |
| 172 state = self.__states[index] | 176 state = self.__states[index] |
| 173 if not state['start_node']: | 177 if not state['start_node']: |
| 174 state['start_node'] = self.__new_state() | 178 state['start_node'] = self.__new_state() |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 return terms[0] if len(terms) == 1 else Term('OR', *terms) | 288 return terms[0] if len(terms) == 1 else Term('OR', *terms) |
| 285 | 289 |
| 286 @staticmethod | 290 @staticmethod |
| 287 def cat_terms(terms): | 291 def cat_terms(terms): |
| 288 terms = NfaBuilder.__flatten_terms(terms, 'CAT') | 292 terms = NfaBuilder.__flatten_terms(terms, 'CAT') |
| 289 terms = list(NfaBuilder.__flatten_literals(terms)) | 293 terms = list(NfaBuilder.__flatten_literals(terms)) |
| 290 assert terms | 294 assert terms |
| 291 return terms[0] if len(terms) == 1 else Term('CAT', *terms) | 295 return terms[0] if len(terms) == 1 else Term('CAT', *terms) |
| 292 | 296 |
| 293 @staticmethod | 297 @staticmethod |
| 294 def nfa(encoding, character_classes, subtree_map, name): | 298 def nfa(encoding, character_classes, subtree_map, |
| 299 name, default_action = Action.empty_action()): |
| 295 self = NfaBuilder(encoding, character_classes, subtree_map) | 300 self = NfaBuilder(encoding, character_classes, subtree_map) |
| 296 (start, ends) = self.__subgraph(name) | 301 (start, ends) = self.__subgraph(name) |
| 297 # close all ends | 302 # close all ends |
| 303 for e in ends: |
| 304 match_node = self.__build_match_node(default_action) |
| 305 e.close(match_node) |
| 306 match_node.close(None) |
| 298 end = self.__global_end | 307 end = self.__global_end |
| 299 end.close(None) | 308 end.close(None) |
| 300 # TODO(dcarney): patch in default action | |
| 301 self.__patch_ends(ends, end) | |
| 302 # Prepare the nfa | 309 # Prepare the nfa |
| 303 self.__compute_epsilon_closures(start) | 310 self.__compute_epsilon_closures(start) |
| 304 f = lambda node, state: self.__replace_catch_all(self.__encoding, node) | 311 f = lambda node, state: self.__replace_catch_all(self.__encoding, node) |
| 305 Automaton.visit_states(set([start]), f) | 312 Automaton.visit_states(set([start]), f) |
| 306 return Nfa(self.__encoding, start, end, self.__node_number) | 313 return Nfa(self.__encoding, start, end, self.__node_number) |
| 307 | 314 |
| 308 @staticmethod | 315 @staticmethod |
| 309 def __compute_epsilon_closures(start_state): | 316 def __compute_epsilon_closures(start_state): |
| 310 def outer(node, state): | 317 def outer(node, state): |
| 311 def inner(node, closure): | 318 def inner(node, closure): |
| (...skipping 23 matching lines...) Expand all Loading... |
| 335 inverse_key = TransitionKey.inverse_key(encoding, keys) | 342 inverse_key = TransitionKey.inverse_key(encoding, keys) |
| 336 if not inverse_key: | 343 if not inverse_key: |
| 337 inverse_key = TransitionKey.unique('no_match') | 344 inverse_key = TransitionKey.unique('no_match') |
| 338 state.swap_key(catch_all, inverse_key) | 345 state.swap_key(catch_all, inverse_key) |
| 339 | 346 |
| 340 @staticmethod | 347 @staticmethod |
| 341 def __install_omega_transitions(start_state, default_action): | 348 def __install_omega_transitions(start_state, default_action): |
| 342 '''install a match transition, a backtrack transition, | 349 '''install a match transition, a backtrack transition, |
| 343 or a default transition into all nodes''' | 350 or a default transition into all nodes''' |
| 344 pass | 351 pass |
| OLD | NEW |