Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: tools/lexer_generator/dfa.py

Issue 82983002: Experimental parser: KeyEncoding class added (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/lexer_generator/code_generator_test.py ('k') | tools/lexer_generator/generator.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 def transition_state_for_key(self, value): 71 def transition_state_for_key(self, value):
72 matches = self.__matches(lambda k, v : k.is_superset_of_key(v), value) 72 matches = self.__matches(lambda k, v : k.is_superset_of_key(v), value)
73 if not matches: 73 if not matches:
74 return None 74 return None
75 # Since this is a dfa, we should have at most one such state. Return it. 75 # Since this is a dfa, we should have at most one such state. Return it.
76 assert len(matches) == 1 76 assert len(matches) == 1
77 return matches[0] 77 return matches[0]
78 78
79 class Dfa(Automaton): 79 class Dfa(Automaton):
80 80
81 def __init__(self, start_name, mapping): 81 def __init__(self, encoding, start_name, mapping):
82 super(Dfa, self).__init__() 82 super(Dfa, self).__init__(encoding)
83 self.__terminal_set = set() 83 self.__terminal_set = set()
84 name_map = {} 84 name_map = {}
85 for name, node_data in mapping.items(): 85 for name, node_data in mapping.items():
86 node = DfaState(name, node_data['action']) 86 node = DfaState(name, node_data['action'])
87 name_map[name] = node 87 name_map[name] = node
88 if node_data['terminal']: 88 if node_data['terminal']:
89 self.__terminal_set.add(node) 89 self.__terminal_set.add(node)
90 for name, node_data in mapping.items(): 90 for name, node_data in mapping.items():
91 node = name_map[name] 91 node = name_map[name]
92 inversion = {} 92 inversion = {}
93 for key, state in node_data['transitions'].items(): 93 for key, state in node_data['transitions'].items():
94 if not state in inversion: 94 if not state in inversion:
95 inversion[state] = [] 95 inversion[state] = []
96 inversion[state].append(key) 96 inversion[state].append(key)
97 for state, keys in inversion.items(): 97 for state, keys in inversion.items():
98 merged_key = TransitionKey.merged_key(keys) 98 merged_key = TransitionKey.merged_key(encoding, keys)
99 node.add_transition(merged_key, name_map[state]) 99 node.add_transition(merged_key, name_map[state])
100 self.__start = name_map[start_name] 100 self.__start = name_map[start_name]
101 self.__node_count = len(mapping) 101 self.__node_count = len(mapping)
102 self.__verify() 102 self.__verify()
103 103
104 def __verify(self): 104 def __verify(self):
105 assert self.__terminal_set 105 assert self.__terminal_set
106 state_count = self.visit_all_states(lambda state, count: count + 1, 0) 106 state_count = self.visit_all_states(lambda state, count: count + 1, 0)
107 assert self.__node_count == state_count 107 assert self.__node_count == state_count
108 108
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 # The alphabet defines the TransitionKeys we need to check when dedicing if 216 # The alphabet defines the TransitionKeys we need to check when dedicing if
217 # two states of the dfa can be in the same partition. See the doc string of 217 # two states of the dfa can be in the same partition. See the doc string of
218 # TransitionKey.disjoint_keys. 218 # TransitionKey.disjoint_keys.
219 219
220 # For example, if the TransitionKeys are {[a-d], [c-h]}, the alphabet is 220 # For example, if the TransitionKeys are {[a-d], [c-h]}, the alphabet is
221 # {[a-b], [c-d], [e-h]}. If state S1 has a transition to S2 with 221 # {[a-b], [c-d], [e-h]}. If state S1 has a transition to S2 with
222 # TransitionKey [a-d], and state S3 has a transition to S4 with 222 # TransitionKey [a-d], and state S3 has a transition to S4 with
223 # TransitionKey [c-h], S1 and S3 cannot be in the same partition. This will 223 # TransitionKey [c-h], S1 and S3 cannot be in the same partition. This will
224 # become clear when we check the transition for TransitionKey [c-d] (S1 has 224 # become clear when we check the transition for TransitionKey [c-d] (S1 has
225 # a transition to S2, S3 has a transition to S4). 225 # a transition to S2, S3 has a transition to S4).
226 self.__alphabet = list(TransitionKey.disjoint_keys(chain(*all_keys))) 226 encoding = self.__dfa.encoding()
227 self.__alphabet = list(
228 TransitionKey.disjoint_keys(encoding, chain(*all_keys)))
227 229
228 # For each state and each TransitionKey in the alphabet, find out which 230 # For each state and each TransitionKey in the alphabet, find out which
229 # transition we take from the state with the TransitionKey. 231 # transition we take from the state with the TransitionKey.
230 transitions = {} 232 transitions = {}
231 for state_id, state in id_to_state.items(): 233 for state_id, state in id_to_state.items():
232 def f((key_id, key)): 234 def f((key_id, key)):
233 transition_state = state.transition_state_for_key(key) 235 transition_state = state.transition_state_for_key(key)
234 if transition_state: 236 if transition_state:
235 return state_to_id[transition_state] 237 return state_to_id[transition_state]
236 return None 238 return None
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 working_set.add(difference) 383 working_set.add(difference)
382 elif len(intersection) <= len(difference): 384 elif len(intersection) <= len(difference):
383 working_set.add(intersection) 385 working_set.add(intersection)
384 else: 386 else:
385 working_set.add(difference) 387 working_set.add(difference)
386 if old_partitions: 388 if old_partitions:
387 partitions -= old_partitions 389 partitions -= old_partitions
388 if new_partitions: 390 if new_partitions:
389 partitions |= new_partitions 391 partitions |= new_partitions
390 (start_name, mapping) = self.__create_states_from_partitions(partitions) 392 (start_name, mapping) = self.__create_states_from_partitions(partitions)
391 return Dfa(start_name, mapping) 393 return Dfa(self.__dfa.encoding(), start_name, mapping)
OLDNEW
« no previous file with comments | « tools/lexer_generator/code_generator_test.py ('k') | tools/lexer_generator/generator.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698