| 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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 except Exception: | 242 except Exception: |
| 243 RuleParser.__static_instance = None | 243 RuleParser.__static_instance = None |
| 244 raise | 244 raise |
| 245 parser.__state = None | 245 parser.__state = None |
| 246 assert parser_state.transitions <= set(parser_state.rules.keys()) | 246 assert parser_state.transitions <= set(parser_state.rules.keys()) |
| 247 | 247 |
| 248 class RuleProcessor(object): | 248 class RuleProcessor(object): |
| 249 | 249 |
| 250 def __init__(self, parser_state): | 250 def __init__(self, parser_state): |
| 251 self.__automata = {} | 251 self.__automata = {} |
| 252 self.__rule_trees = {} | |
| 253 self.__default_action = None | 252 self.__default_action = None |
| 254 self.__process_parser_state(parser_state) | 253 self.__process_parser_state(parser_state) |
| 255 | 254 |
| 256 @staticmethod | 255 @staticmethod |
| 257 def parse(string, encoding_name): | 256 def parse(string, encoding_name): |
| 258 parser_state = RuleParserState(KeyEncoding.get(encoding_name)) | 257 parser_state = RuleParserState(KeyEncoding.get(encoding_name)) |
| 259 RuleParser.parse(string, parser_state) | 258 RuleParser.parse(string, parser_state) |
| 260 return RuleProcessor(parser_state) | 259 return RuleProcessor(parser_state) |
| 261 | 260 |
| 262 def automata_iter(self): | 261 def automata_iter(self): |
| 263 return iter(self.__automata.items()) | 262 return iter(self.__automata.items()) |
| 264 | 263 |
| 265 def default_automata(self): | 264 def default_automata(self): |
| 266 return self.__automata['default'] | 265 return self.__automata['default'] |
| 267 | 266 |
| 268 def default_action(self): | 267 def default_action(self): |
| 269 return self.__default_action | 268 return self.__default_action |
| 270 | 269 |
| 271 class Automata(object): | 270 class Automata(object): |
| 271 'a container for the resulting automata, which are lazily built' |
| 272 | 272 |
| 273 def __init__(self, encoding, character_classes, rule_term): | 273 def __init__(self, encoding, character_classes, rule_map, name): |
| 274 self.__encoding = encoding | 274 self.__encoding = encoding |
| 275 self.__character_classes = character_classes | 275 self.__character_classes = character_classes |
| 276 self.__rule_term = rule_term | 276 self.__rule_map = rule_map |
| 277 self.__name = name |
| 277 self.__nfa = None | 278 self.__nfa = None |
| 278 self.__dfa = None | 279 self.__dfa = None |
| 279 self.__minimial_dfa = None | 280 self.__minimial_dfa = None |
| 280 | 281 |
| 282 def name(self): |
| 283 return self.__name |
| 284 |
| 281 def rule_term(self): | 285 def rule_term(self): |
| 282 return self.__rule_term | 286 return self.__rule_map[self.__name] |
| 283 | 287 |
| 284 def nfa(self): | 288 def nfa(self): |
| 285 if not self.__nfa: | 289 if not self.__nfa: |
| 286 self.__nfa = NfaBuilder.nfa( | 290 self.__nfa = NfaBuilder.nfa( |
| 287 self.__encoding, self.__character_classes, self.__rule_term) | 291 self.__encoding, self.__character_classes, |
| 292 self.__rule_map, self.__name) |
| 288 return self.__nfa | 293 return self.__nfa |
| 289 | 294 |
| 290 def dfa(self): | 295 def dfa(self): |
| 291 if not self.__dfa: | 296 if not self.__dfa: |
| 292 (start, dfa_nodes) = self.nfa().compute_dfa() | 297 (start, dfa_nodes) = self.nfa().compute_dfa() |
| 293 self.__dfa = Dfa(self.nfa().encoding(), start, dfa_nodes) | 298 self.__dfa = Dfa(self.nfa().encoding(), start, dfa_nodes) |
| 294 return self.__dfa | 299 return self.__dfa |
| 295 | 300 |
| 296 def optimize_dfa(self, log = False): | 301 def optimize_dfa(self, log = False): |
| 297 assert not self.__dfa | 302 assert not self.__dfa |
| 298 assert not self.__minimial_dfa | 303 assert not self.__minimial_dfa |
| 299 self.__dfa = DfaOptimizer.optimize(self.minimal_dfa(), log) | 304 self.__dfa = DfaOptimizer.optimize(self.minimal_dfa(), log) |
| 300 self.__minimial_dfa = None | 305 self.__minimial_dfa = None |
| 301 | 306 |
| 302 def minimal_dfa(self): | 307 def minimal_dfa(self): |
| 303 if not self.__minimial_dfa: | 308 if not self.__minimial_dfa: |
| 304 self.__minimial_dfa = self.dfa().minimize() | 309 self.__minimial_dfa = self.dfa().minimize() |
| 305 return self.__minimial_dfa | 310 return self.__minimial_dfa |
| 306 | 311 |
| 307 def __process_parser_state(self, parser_state): | 312 def __process_parser_state(self, parser_state): |
| 313 assert 'default' in parser_state.rules |
| 308 rule_map = {} | 314 rule_map = {} |
| 309 assert 'default' in parser_state.rules | 315 def process(tree_name, v): |
| 310 def process(subgraph, v): | 316 trees = [] |
| 311 graphs = [] | 317 for tree, precedence, action in v['regex']: |
| 312 for graph, precedence, action in v['regex']: | |
| 313 (entry_action, match_action, transition) = action | 318 (entry_action, match_action, transition) = action |
| 314 if entry_action or match_action: | 319 if entry_action or match_action: |
| 315 graph = NfaBuilder.add_action( | 320 tree = NfaBuilder.add_action( |
| 316 graph, Action(entry_action, match_action, precedence)) | 321 tree, Action(entry_action, match_action, precedence)) |
| 317 if not transition: | 322 if not transition: |
| 318 pass | 323 pass |
| 319 elif transition == 'continue': | 324 elif transition == 'continue': |
| 320 assert not subgraph == 'default', 'unimplemented' | 325 tree = NfaBuilder.add_continue(tree) |
| 321 graph = NfaBuilder.add_continue(graph) | |
| 322 else: | 326 else: |
| 323 assert subgraph == 'default', 'unimplemented' | 327 tree = NfaBuilder.join_subtree(tree, transition) |
| 324 graph = NfaBuilder.join_subgraph( | 328 trees.append(tree) |
| 325 graph, rule_map[transition]) | 329 rule_map[tree_name] = NfaBuilder.or_terms(trees) |
| 326 graphs.append(graph) | 330 # process all subgraphs |
| 327 graph = NfaBuilder.or_terms(graphs) | |
| 328 rule_map[subgraph] = graph | |
| 329 # process first the subgraphs, then the default graph | |
| 330 for k, v in parser_state.rules.items(): | 331 for k, v in parser_state.rules.items(): |
| 331 if k == 'default': continue | |
| 332 process(k, v) | 332 process(k, v) |
| 333 process('default', parser_state.rules['default']) | |
| 334 # build the automata | 333 # build the automata |
| 335 for rule_name, graph in rule_map.items(): | 334 for name, tree in rule_map.items(): |
| 336 self.__automata[rule_name] = RuleProcessor.Automata( | 335 self.__automata[name] = RuleProcessor.Automata( |
| 337 parser_state.encoding, parser_state.character_classes, graph) | 336 parser_state.encoding, parser_state.character_classes, rule_map, name) |
| 338 self.__rule_trees[rule_name] = graph | |
| 339 # process default_action | 337 # process default_action |
| 340 default_action = parser_state.rules['default']['default_action'] | 338 default_action = parser_state.rules['default']['default_action'] |
| 341 self.__default_action = Action(Term.empty_term(), default_action) | 339 self.__default_action = Action(Term.empty_term(), default_action) |
| OLD | NEW |