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

Side by Side Diff: tools/lexer_generator/nfa_builder.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/nfa.py ('k') | 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 13 matching lines...) Expand all
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 from types import TupleType 28 from types import TupleType
29 from inspect import getmembers 29 from inspect import getmembers
30 from nfa import * 30 from nfa import *
31 31
32 class NfaBuilder(object): 32 class NfaBuilder(object):
33 33
34 def __init__(self): 34 def __init__(self, encoding, character_classes = {}):
35 self.__node_number = 0 35 self.__node_number = 0
36 self.__operation_map = {} 36 self.__operation_map = {}
37 self.__members = getmembers(self) 37 self.__members = getmembers(self)
38 self.__character_classes = {} 38 self.__encoding = encoding
39 self.__character_classes = character_classes
39 self.__states = [] 40 self.__states = []
40 41
41 def set_character_classes(self, classes):
42 self.__character_classes = classes
43
44 def __new_state(self): 42 def __new_state(self):
45 self.__node_number += 1 43 self.__node_number += 1
46 return NfaState() 44 return NfaState()
47 45
48 def __or(self, graph): 46 def __or(self, graph):
49 start = self.__new_state() 47 start = self.__new_state()
50 ends = [] 48 ends = []
51 for x in [self.__process(graph[1]), self.__process(graph[2])]: 49 for x in [self.__process(graph[1]), self.__process(graph[2])]:
52 start.add_epsilon_transition(x[0]) 50 start.add_epsilon_transition(x[0])
53 ends += x[1] 51 ends += x[1]
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 (left, right) = (self.__process(graph[1]), self.__process(graph[2])) 98 (left, right) = (self.__process(graph[1]), self.__process(graph[2]))
101 self.__patch_ends(left[1], right[0]) 99 self.__patch_ends(left[1], right[0])
102 return (left[0], right[1]) 100 return (left[0], right[1])
103 101
104 def __key_state(self, key): 102 def __key_state(self, key):
105 state = self.__new_state() 103 state = self.__new_state()
106 state.add_unclosed_transition(key) 104 state.add_unclosed_transition(key)
107 return (state, [state]) 105 return (state, [state])
108 106
109 def __literal(self, graph): 107 def __literal(self, graph):
110 return self.__key_state(TransitionKey.single_char(graph[1])) 108 return self.__key_state(
109 TransitionKey.single_char(self.__encoding, graph[1]))
111 110
112 def __class(self, graph): 111 def __class(self, graph):
113 return self.__key_state( 112 return self.__key_state(TransitionKey.character_class(
114 TransitionKey.character_class(graph, self.__character_classes)) 113 self.__encoding, graph, self.__character_classes))
115 114
116 def __not_class(self, graph): 115 def __not_class(self, graph):
117 return self.__key_state( 116 return self.__key_state(TransitionKey.character_class(
118 TransitionKey.character_class(graph, self.__character_classes)) 117 self.__encoding, graph, self.__character_classes))
119 118
120 def __any(self, graph): 119 def __any(self, graph):
121 return self.__key_state(TransitionKey.any()) 120 return self.__key_state(TransitionKey.any(self.__encoding))
122 121
123 def __epsilon(self, graph): 122 def __epsilon(self, graph):
124 start = self.__new_state() 123 start = self.__new_state()
125 end = self.__new_state() 124 end = self.__new_state()
126 start.close(end) 125 start.close(end)
127 return (start, [end]) 126 return (start, [end])
128 127
129 def __action(self, graph): 128 def __action(self, graph):
130 (start, ends) = self.__process(graph[1]) 129 (start, ends) = self.__process(graph[1])
131 action = graph[2] 130 action = graph[2]
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 return closure 208 return closure
210 is_epsilon = lambda k: k == TransitionKey.epsilon() 209 is_epsilon = lambda k: k == TransitionKey.epsilon()
211 state_iter = lambda node : node.state_iter(key_filter = is_epsilon) 210 state_iter = lambda node : node.state_iter(key_filter = is_epsilon)
212 edge = set(state_iter(node)) 211 edge = set(state_iter(node))
213 closure = Automaton.visit_states( 212 closure = Automaton.visit_states(
214 edge, inner, state_iter=state_iter, visit_state=set()) 213 edge, inner, state_iter=state_iter, visit_state=set())
215 node.set_epsilon_closure(closure) 214 node.set_epsilon_closure(closure)
216 Automaton.visit_states(set([start_state]), outer) 215 Automaton.visit_states(set([start_state]), outer)
217 216
218 @staticmethod 217 @staticmethod
219 def __replace_catch_all(state): 218 def __replace_catch_all(encoding, state):
220 catch_all = TransitionKey.unique('catch_all') 219 catch_all = TransitionKey.unique('catch_all')
221 transitions = state.transitions() 220 transitions = state.transitions()
222 if not catch_all in transitions: 221 if not catch_all in transitions:
223 return 222 return
224 f = lambda acc, state: acc | set(state.epsilon_closure_iter()) 223 f = lambda acc, state: acc | set(state.epsilon_closure_iter())
225 reachable_states = reduce(f, transitions[catch_all], set()) 224 reachable_states = reduce(f, transitions[catch_all], set())
226 f = lambda acc, state: acc | set(state.transitions().keys()) 225 f = lambda acc, state: acc | set(state.transitions().keys())
227 keys = reduce(f, reachable_states, set()) 226 keys = reduce(f, reachable_states, set())
228 keys.discard(TransitionKey.epsilon()) 227 keys.discard(TransitionKey.epsilon())
229 keys.discard(catch_all) 228 keys.discard(catch_all)
230 inverse_key = TransitionKey.inverse_key(keys) 229 inverse_key = TransitionKey.inverse_key(encoding, keys)
231 if inverse_key: 230 if inverse_key:
232 transitions[inverse_key] = transitions[catch_all] 231 transitions[inverse_key] = transitions[catch_all]
233 del transitions[catch_all] 232 del transitions[catch_all]
234 233
235 def nfa(self, graph): 234 def nfa(self, graph):
236 (start, end, nodes_created) = self.__nfa(graph) 235 (start, end, nodes_created) = self.__nfa(graph)
237 end.close(None) 236 end.close(None)
238 self.__compute_epsilon_closures(start) 237 self.__compute_epsilon_closures(start)
239 f = lambda node, state: self.__replace_catch_all(node) 238 f = lambda node, state: self.__replace_catch_all(self.__encoding, node)
240 Automaton.visit_states(set([start]), f) 239 Automaton.visit_states(set([start]), f)
241 return Nfa(start, end, nodes_created) 240 return Nfa(self.__encoding, start, end, nodes_created)
242 241
243 @staticmethod 242 @staticmethod
244 def add_action(graph, action): 243 def add_action(graph, action):
245 return ('ACTION', graph, action) 244 return ('ACTION', graph, action)
246 245
247 @staticmethod 246 @staticmethod
248 def add_continue(graph): 247 def add_continue(graph):
249 return ('CONTINUE', graph) 248 return ('CONTINUE', graph)
250 249
251 @staticmethod 250 @staticmethod
(...skipping 18 matching lines...) Expand all
270 269
271 __modifer_map = { 270 __modifer_map = {
272 '+': 'ONE_OR_MORE', 271 '+': 'ONE_OR_MORE',
273 '?': 'ZERO_OR_ONE', 272 '?': 'ZERO_OR_ONE',
274 '*': 'ZERO_OR_MORE', 273 '*': 'ZERO_OR_MORE',
275 } 274 }
276 275
277 @staticmethod 276 @staticmethod
278 def apply_modifier(modifier, graph): 277 def apply_modifier(modifier, graph):
279 return (NfaBuilder.__modifer_map[modifier], graph) 278 return (NfaBuilder.__modifer_map[modifier], graph)
OLDNEW
« no previous file with comments | « tools/lexer_generator/nfa.py ('k') | tools/lexer_generator/rule_parser.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698