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

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

Issue 141083011: Experimental parser: always add all subtrees (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: fix Created 6 years, 10 months 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 | « no previous file | tools/lexer_generator/rule_parser.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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 (start, ends) = self.__process(subtree) 149 (start, ends) = self.__process(subtree)
150 state = self.__peek_state() 150 state = self.__peek_state()
151 if not state['start_node']: 151 if not state['start_node']:
152 state['start_node'] = self.__new_state() 152 state['start_node'] = self.__new_state()
153 self.__patch_ends(ends, state['start_node']) 153 self.__patch_ends(ends, state['start_node'])
154 return (start, []) 154 return (start, [])
155 155
156 def __unique_key(self, name): 156 def __unique_key(self, name):
157 return self.__key_state(TransitionKey.unique(name)) 157 return self.__key_state(TransitionKey.unique(name))
158 158
159 def __join(self, graph, name, subgraph): 159 def __join(self, tree, subtree):
160 subgraphs = self.__peek_state()['subgraphs'] 160 (subtree_start, subtree_end, nodes_in_subtree) = self.__nfa(subtree)
161 if not name in subgraphs: 161 (start, ends) = self.__process(tree)
162 subgraphs[name] = self.__nfa(subgraph) 162 self.__patch_ends(ends, subtree_start)
163 (subgraph_start, subgraph_end, nodes_in_subgraph) = subgraphs[name] 163 if subtree_end:
164 (start, ends) = self.__process(graph) 164 return (start, [subtree_end])
165 self.__patch_ends(ends, subgraph_start)
166 if subgraph_end:
167 end = self.__new_state()
168 subgraph_end.add_epsilon_transition(end)
169 return (start, [end])
170 else: 165 else:
171 return (start, []) 166 return (start, [])
172 167
173 def __process(self, term): 168 def __process(self, term):
174 assert isinstance(term, Term) 169 assert isinstance(term, Term)
175 method = "_NfaBuilder__" + term.name().lower() 170 method = "_NfaBuilder__" + term.name().lower()
176 if not method in self.__operation_map: 171 if not method in self.__operation_map:
177 matches = filter(lambda (name, func): name == method, self.__members) 172 matches = filter(lambda (name, func): name == method, self.__members)
178 assert len(matches) == 1 173 assert len(matches) == 1
179 self.__operation_map[method] = matches[0][1] 174 self.__operation_map[method] = matches[0][1]
180 return self.__operation_map[method](*term.args()) 175 return self.__operation_map[method](*term.args())
181 176
182 def __patch_ends(self, ends, new_end): 177 def __patch_ends(self, ends, new_end):
183 for end in ends: 178 for end in ends:
184 end.close(new_end) 179 end.close(new_end)
185 180
186 def __push_state(self): 181 def __push_state(self):
187 self.__states.append({ 182 self.__states.append({
188 'start_node' : None, 183 'start_node' : None,
189 'subgraphs' : {},
190 'unpatched_ends' : [],
191 }) 184 })
192 185
193 def __pop_state(self): 186 def __pop_state(self):
194 return self.__states.pop() 187 return self.__states.pop()
195 188
196 def __peek_state(self): 189 def __peek_state(self):
197 return self.__states[-1] 190 return self.__states[-1]
198 191
199 def __nfa(self, term): 192 def __nfa(self, term):
200 start_node_number = self.__node_number 193 start_node_number = self.__node_number
201 self.__push_state() 194 self.__push_state()
202 (start, ends) = self.__process(term) 195 (start, ends) = self.__process(term)
203 state = self.__pop_state() 196 state = self.__pop_state()
204 if state['start_node']: 197 if state['start_node']:
205 state['start_node'].close(start) 198 state['start_node'].close(start)
206 start = state['start_node'] 199 start = state['start_node']
207 for k, subgraph in state['subgraphs'].items():
208 if subgraph[1]:
209 subgraph[1].close(None)
210
211 # Don't create an end node for the subgraph if it would be unused (ends can 200 # Don't create an end node for the subgraph if it would be unused (ends can
212 # be an empty list e.g., in the case when everything inside the subgraph is 201 # be an empty list e.g., in the case when everything inside the subgraph is
213 # "continue"). 202 # "continue").
214 end = None 203 end = None
215 if ends: 204 if ends:
216 end = self.__new_state() 205 end = self.__new_state()
217 self.__patch_ends(ends, end) 206 self.__patch_ends(ends, end)
218
219 return (start, end, self.__node_number - start_node_number) 207 return (start, end, self.__node_number - start_node_number)
220 208
221 @staticmethod 209 @staticmethod
222 def __compute_epsilon_closures(start_state): 210 def __compute_epsilon_closures(start_state):
223 def outer(node, state): 211 def outer(node, state):
224 def inner(node, closure): 212 def inner(node, closure):
225 closure.add(node) 213 closure.add(node)
226 return closure 214 return closure
227 is_epsilon = lambda k: k == TransitionKey.epsilon() 215 is_epsilon = lambda k: k == TransitionKey.epsilon()
228 state_iter = lambda node : node.state_iter(key_filter = is_epsilon) 216 state_iter = lambda node : node.state_iter(key_filter = is_epsilon)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 263
276 @staticmethod 264 @staticmethod
277 def add_continue(term): 265 def add_continue(term):
278 return Term('CONTINUE', term) 266 return Term('CONTINUE', term)
279 267
280 @staticmethod 268 @staticmethod
281 def unique_key(name): 269 def unique_key(name):
282 return Term('UNIQUE_KEY', name) 270 return Term('UNIQUE_KEY', name)
283 271
284 @staticmethod 272 @staticmethod
285 def join_subgraph(term, name, subgraph_term): 273 def join_subgraph(tree, subtree):
286 return Term('JOIN', term, name, subgraph_term) 274 return Term('JOIN', tree, subtree)
287 275
288 @staticmethod 276 @staticmethod
289 def or_terms(terms): 277 def or_terms(terms):
290 return reduce(lambda acc, g: Term('OR', acc, g), terms) 278 return reduce(lambda acc, g: Term('OR', acc, g), terms)
291 279
292 @staticmethod 280 @staticmethod
293 def cat_terms(terms): 281 def cat_terms(terms):
294 return reduce(lambda acc, g: Term('CAT', acc, g), terms) 282 return reduce(lambda acc, g: Term('CAT', acc, g), terms)
295 283
296 __modifer_map = { 284 __modifer_map = {
297 '+': 'ONE_OR_MORE', 285 '+': 'ONE_OR_MORE',
298 '?': 'ZERO_OR_ONE', 286 '?': 'ZERO_OR_ONE',
299 '*': 'ZERO_OR_MORE', 287 '*': 'ZERO_OR_MORE',
300 } 288 }
301 289
302 @staticmethod 290 @staticmethod
303 def apply_modifier(modifier, term): 291 def apply_modifier(modifier, term):
304 return Term(NfaBuilder.__modifer_map[modifier], term) 292 return Term(NfaBuilder.__modifer_map[modifier], term)
OLDNEW
« no previous file with comments | « no previous file | tools/lexer_generator/rule_parser.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698