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

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

Issue 54533002: Experimental parser: more tests, better key logic (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/automata_test.py ('k') | tools/lexer_generator/transition_key_test.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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 self.__add_transition(key, end) 86 self.__add_transition(key, end)
87 if not self.__unclosed: 87 if not self.__unclosed:
88 self.add_epsilon_transition(end) 88 self.add_epsilon_transition(end)
89 self.__unclosed = None 89 self.__unclosed = None
90 90
91 def __matches(self, match_func, value): 91 def __matches(self, match_func, value):
92 f = lambda acc, (k, vs): acc | vs if match_func(k, value) else acc 92 f = lambda acc, (k, vs): acc | vs if match_func(k, value) else acc
93 return reduce(f, self.__transitions.items(), set()) 93 return reduce(f, self.__transitions.items(), set())
94 94
95 def char_matches(self, value): 95 def char_matches(self, value):
96 return self.__matches((lambda k, v : k.matches_char(v)), value) 96 return self.__matches(lambda k, v : k.matches_char(v), value)
97 97
98 def key_matches(self, value): 98 def key_matches(self, value):
99 return self.__matches((lambda k, v : k.matches_key(v)), value) 99 return self.__matches(lambda k, v : k.matches_key(v), value)
100 100
101 @staticmethod 101 @staticmethod
102 def gather_transition_keys(state_set): 102 def gather_transition_keys(state_set):
103 f = lambda acc, state: acc | set(state.__transitions.keys()) 103 f = lambda acc, state: acc | set(state.__transitions.keys())
104 return TransitionKey.merge_key_set(reduce(f, state_set, set())) 104 return TransitionKey.disjoint_keys(reduce(f, state_set, set()))
105 105
106 class NfaBuilder: 106 class NfaBuilder:
107 107
108 def __init__(self): 108 def __init__(self):
109 self.__operation_map = {} 109 self.__operation_map = {}
110 self.__members = getmembers(self) 110 self.__members = getmembers(self)
111 111
112 def __new_state(self): 112 def __new_state(self):
113 node_number = self.node_number 113 node_number = self.node_number
114 self.node_number = self.node_number + 1 114 self.node_number = self.node_number + 1
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 def __not_class(self, graph): 162 def __not_class(self, graph):
163 return self.__key_state(TransitionKey.character_class(True, graph[1])) 163 return self.__key_state(TransitionKey.character_class(True, graph[1]))
164 164
165 def __any(self, graph): 165 def __any(self, graph):
166 return self.__key_state(TransitionKey.any()) 166 return self.__key_state(TransitionKey.any())
167 167
168 def __process(self, graph): 168 def __process(self, graph):
169 assert type(graph) == TupleType 169 assert type(graph) == TupleType
170 method = "_NfaBuilder__" + graph[0].lower() 170 method = "_NfaBuilder__" + graph[0].lower()
171 if not method in self.__operation_map: 171 if not method in self.__operation_map:
172 matches = filter((lambda (name, func): name == method), self.__members) 172 matches = filter(lambda (name, func): name == method, self.__members)
173 assert len(matches) == 1 173 assert len(matches) == 1
174 self.__operation_map[method] = matches[0][1] 174 self.__operation_map[method] = matches[0][1]
175 return self.__operation_map[method](graph) 175 return self.__operation_map[method](graph)
176 176
177 def __patch_ends(self, ends, new_end): 177 def __patch_ends(self, ends, new_end):
178 for end in ends: 178 for end in ends:
179 end.close(new_end) 179 end.close(new_end)
180 180
181 def nfa(self, graph): 181 def nfa(self, graph):
182 self.node_number = 0 182 self.node_number = 0
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 for c in string: 246 for c in string:
247 f = lambda acc, state: acc | state.char_matches(c) 247 f = lambda acc, state: acc | state.char_matches(c)
248 valid_states = Nfa.__close(reduce(f, valid_states, set())) 248 valid_states = Nfa.__close(reduce(f, valid_states, set()))
249 if not valid_states: 249 if not valid_states:
250 return False 250 return False
251 return self.__end in valid_states 251 return self.__end in valid_states
252 252
253 @staticmethod 253 @staticmethod
254 def __to_dfa(nfa_state_set, builder): 254 def __to_dfa(nfa_state_set, builder):
255 nfa_state_set = Nfa.__close(nfa_state_set) 255 nfa_state_set = Nfa.__close(nfa_state_set)
256 assert nfa_state_set
256 name = str([x.node_number() for x in nfa_state_set]) 257 name = str([x.node_number() for x in nfa_state_set])
257 (dfa_nodes, end_nodes, end_node) = builder 258 (dfa_nodes, end_nodes, end_node) = builder
258 if name in dfa_nodes: 259 if name in dfa_nodes:
259 return name 260 return name
260 dfa_node = {} 261 dfa_node = {}
261 dfa_nodes[name] = dfa_node 262 dfa_nodes[name] = dfa_node
262 for key in NfaState.gather_transition_keys(nfa_state_set): 263 for key in NfaState.gather_transition_keys(nfa_state_set):
263 f = lambda acc, state: acc | state.key_matches(key) 264 f = lambda acc, state: acc | state.key_matches(key)
264 dfa_node[key] = Nfa.__to_dfa(reduce(f, nfa_state_set, set()), builder) 265 dfa_node[key] = Nfa.__to_dfa(reduce(f, nfa_state_set, set()), builder)
265 if end_node in nfa_state_set: 266 if end_node in nfa_state_set:
(...skipping 26 matching lines...) Expand all
292 digraph finite_state_machine { 293 digraph finite_state_machine {
293 rankdir=LR; 294 rankdir=LR;
294 node [shape = circle, style=filled, bgcolor=lightgrey]; S_%s 295 node [shape = circle, style=filled, bgcolor=lightgrey]; S_%s
295 node [shape = doublecircle, style=unfilled]; S_%s 296 node [shape = doublecircle, style=unfilled]; S_%s
296 node [shape = circle]; 297 node [shape = circle];
297 %s 298 %s
298 } 299 }
299 ''' % (self.__start.node_number(), 300 ''' % (self.__start.node_number(),
300 self.__end.node_number(), 301 self.__end.node_number(),
301 "\n".join(node_content)) 302 "\n".join(node_content))
OLDNEW
« no previous file with comments | « tools/lexer_generator/automata_test.py ('k') | tools/lexer_generator/transition_key_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698