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

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

Issue 68343006: Experimental parser: add break instruction (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/generator.py ('k') | no next file » | 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 (start, ends) = self.__process(graph[1]) 214 (start, ends) = self.__process(graph[1])
215 state = self.__peek_state() 215 state = self.__peek_state()
216 if not state['start_node']: 216 if not state['start_node']:
217 state['start_node'] = self.__new_state() 217 state['start_node'] = self.__new_state()
218 end = self.__new_state() 218 end = self.__new_state()
219 self.__patch_ends(ends, end) 219 self.__patch_ends(ends, end)
220 ends = [end] 220 ends = [end]
221 end.add_epsilon_transition(state['start_node']) 221 end.add_epsilon_transition(state['start_node'])
222 return (start, ends) 222 return (start, ends)
223 223
224 def __break(self, graph):
225 (start, ends) = self.__process(graph[1])
226 self.__peek_state()['unpatched_ends'] += ends
227 new_end = self.__new_state()
228 for end in ends:
229 end.add_epsilon_transition(new_end)
230 return (start, [new_end])
231
224 def __join(self, graph): 232 def __join(self, graph):
225 (graph, name, subgraph, modifier) = graph[1:] 233 (graph, name, subgraph, modifier) = graph[1:]
226 subgraphs = self.__peek_state()['subgraphs'] 234 subgraphs = self.__peek_state()['subgraphs']
227 if not name in subgraphs: 235 if not name in subgraphs:
228 subgraphs[name] = self.__nfa(subgraph) 236 subgraphs[name] = self.__nfa(subgraph)
229 (subgraph_start, subgraph_end, nodes_in_subgraph) = subgraphs[name] 237 (subgraph_start, subgraph_end, nodes_in_subgraph) = subgraphs[name]
230 (start, ends) = self.__process(graph) 238 (start, ends) = self.__process(graph)
231 if modifier: 239 if modifier:
232 assert modifier == 'ZERO_OR_MORE' 240 assert modifier == 'ZERO_OR_MORE'
233 for end in ends: 241 for end in ends:
(...skipping 13 matching lines...) Expand all
247 return self.__operation_map[method](graph) 255 return self.__operation_map[method](graph)
248 256
249 def __patch_ends(self, ends, new_end): 257 def __patch_ends(self, ends, new_end):
250 for end in ends: 258 for end in ends:
251 end.close(new_end) 259 end.close(new_end)
252 260
253 def __push_state(self): 261 def __push_state(self):
254 self.__states.append({ 262 self.__states.append({
255 'start_node' : None, 263 'start_node' : None,
256 'subgraphs' : {}, 264 'subgraphs' : {},
265 'unpatched_ends' : [],
257 }) 266 })
258 267
259 def __pop_state(self): 268 def __pop_state(self):
260 return self.__states.pop() 269 return self.__states.pop()
261 270
262 def __peek_state(self): 271 def __peek_state(self):
263 return self.__states[len(self.__states) - 1] 272 return self.__states[len(self.__states) - 1]
264 273
265 def __nfa(self, graph): 274 def __nfa(self, graph):
266 start_node_number = self.__node_number 275 start_node_number = self.__node_number
267 self.__push_state() 276 self.__push_state()
268 (start, ends) = self.__process(graph) 277 (start, ends) = self.__process(graph)
269 state = self.__pop_state() 278 state = self.__pop_state()
270 if state['start_node']: 279 if state['start_node']:
271 state['start_node'].close(start) 280 state['start_node'].close(start)
272 start = state['start_node'] 281 start = state['start_node']
273 for k, subgraph in state['subgraphs'].items(): 282 for k, subgraph in state['subgraphs'].items():
274 subgraph[1].close(None) 283 subgraph[1].close(None)
275 end = self.__new_state() 284 end = self.__new_state()
285 if self.__states:
286 self.__peek_state()['unpatched_ends'] += state['unpatched_ends']
287 else:
288 self.__patch_ends(state['unpatched_ends'], end)
276 self.__patch_ends(ends, end) 289 self.__patch_ends(ends, end)
277 return (start, end, self.__node_number - start_node_number) 290 return (start, end, self.__node_number - start_node_number)
278 291
279 def nfa(self, graph): 292 def nfa(self, graph):
280 (start, end, nodes_created) = self.__nfa(graph) 293 (start, end, nodes_created) = self.__nfa(graph)
281 end.close(None) 294 end.close(None)
282 return Nfa(start, end, nodes_created) 295 return Nfa(start, end, nodes_created)
283 296
284 @staticmethod 297 @staticmethod
285 def add_action(graph, action): 298 def add_action(graph, action):
286 return ('ACTION', graph, action) 299 return ('ACTION', graph, action)
287 300
288 @staticmethod 301 @staticmethod
289 def add_continue(graph): 302 def add_continue(graph):
290 return ('CONTINUE', graph) 303 return ('CONTINUE', graph)
291 304
292 @staticmethod 305 @staticmethod
306 def add_break(graph):
307 return ('BREAK', graph)
308
309 @staticmethod
293 def join_subgraph(graph, name, subgraph, modifier): 310 def join_subgraph(graph, name, subgraph, modifier):
294 if modifier: 311 if modifier:
295 modifier = NfaBuilder.__modifer_map[modifier] 312 modifier = NfaBuilder.__modifer_map[modifier]
296 return ('JOIN', graph, name, subgraph, modifier) 313 return ('JOIN', graph, name, subgraph, modifier)
297 314
298 @staticmethod 315 @staticmethod
299 def or_graphs(graphs): 316 def or_graphs(graphs):
300 return reduce(lambda acc, g: ('OR', acc, g), graphs) 317 return reduce(lambda acc, g: ('OR', acc, g), graphs)
301 318
302 @staticmethod 319 @staticmethod
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 def compute_dfa(self): 414 def compute_dfa(self):
398 self.__compute_epsilon_closures() 415 self.__compute_epsilon_closures()
399 dfa_nodes = {} 416 dfa_nodes = {}
400 start_name = self.__to_dfa(set([self.__start]), dfa_nodes, self.__end) 417 start_name = self.__to_dfa(set([self.__start]), dfa_nodes, self.__end)
401 return (start_name, dfa_nodes) 418 return (start_name, dfa_nodes)
402 419
403 def to_dot(self): 420 def to_dot(self):
404 iterator = lambda visitor, state: self.__visit_all_edges(visitor, state) 421 iterator = lambda visitor, state: self.__visit_all_edges(visitor, state)
405 state_iterator = lambda x : x 422 state_iterator = lambda x : x
406 return self.generate_dot(self.__start, set([self.__end]), iterator, state_it erator) 423 return self.generate_dot(self.__start, set([self.__end]), iterator, state_it erator)
OLDNEW
« no previous file with comments | « tools/lexer_generator/generator.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698