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

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

Issue 133353006: Experimental parser: use names instead of offsets in nfabuilder dispatch (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: 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 | 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 def __new_state(self): 53 def __new_state(self):
54 self.__node_number += 1 54 self.__node_number += 1
55 return NfaState() 55 return NfaState()
56 56
57 def __global_end(self): 57 def __global_end(self):
58 if not self.__global_end_node: 58 if not self.__global_end_node:
59 self.__global_end_node = self.__new_state() 59 self.__global_end_node = self.__new_state()
60 return self.__global_end_node 60 return self.__global_end_node
61 61
62 def __or(self, args): 62 def __or(self, left, right):
63 start = self.__new_state() 63 start = self.__new_state()
64 ends = [] 64 ends = []
65 for x in [self.__process(args[0]), self.__process(args[1])]: 65 for (sub_start, sub_end) in [self.__process(left), self.__process(right)]:
66 start.add_epsilon_transition(x[0]) 66 start.add_epsilon_transition(sub_start)
67 ends += x[1] 67 ends += sub_end
68 start.close(None) 68 start.close(None)
69 return (start, ends) 69 return (start, ends)
70 70
71 def __one_or_more(self, args): 71 def __one_or_more(self, subtree):
72 (start, ends) = self.__process(args[0]) 72 (start, ends) = self.__process(subtree)
73 end = self.__new_state() 73 end = self.__new_state()
74 end.add_epsilon_transition(start) 74 end.add_epsilon_transition(start)
75 self.__patch_ends(ends, end) 75 self.__patch_ends(ends, end)
76 return (start, [end]) 76 return (start, [end])
77 77
78 def __zero_or_more(self, args): 78 def __zero_or_more(self, subtree):
79 (node, ends) = self.__process(args[0]) 79 (node, ends) = self.__process(subtree)
80 start = self.__new_state() 80 start = self.__new_state()
81 start.add_epsilon_transition(node) 81 start.add_epsilon_transition(node)
82 self.__patch_ends(ends, start) 82 self.__patch_ends(ends, start)
83 return (start, [start]) 83 return (start, [start])
84 84
85 def __zero_or_one(self, args): 85 def __zero_or_one(self, subtree):
86 (node, ends) = self.__process(args[0]) 86 (node, ends) = self.__process(subtree)
87 start = self.__new_state() 87 start = self.__new_state()
88 start.add_epsilon_transition(node) 88 start.add_epsilon_transition(node)
89 return (start, ends + [start]) 89 return (start, ends + [start])
90 90
91 def __repeat(self, args): 91 def __repeat(self, param_min, param_max, subtree):
92 param_min = int(args[0]) 92 param_min = int(param_min)
93 param_max = int(args[1]) 93 param_max = int(param_max)
94 subgraph = args[2] 94 (start, ends) = self.__process(subtree)
95 (start, ends) = self.__process(subgraph)
96 for i in xrange(1, param_min): 95 for i in xrange(1, param_min):
97 (start2, ends2) = self.__process(subgraph) 96 (start2, ends2) = self.__process(subtree)
98 self.__patch_ends(ends, start2) 97 self.__patch_ends(ends, start2)
99 ends = ends2 98 ends = ends2
100 if param_min == param_max: 99 if param_min == param_max:
101 return (start, ends) 100 return (start, ends)
102 101
103 midpoints = [] 102 midpoints = []
104 for i in xrange(param_min, param_max): 103 for i in xrange(param_min, param_max):
105 midpoint = self.__new_state() 104 midpoint = self.__new_state()
106 self.__patch_ends(ends, midpoint) 105 self.__patch_ends(ends, midpoint)
107 (start2, ends) = self.__process(subgraph) 106 (start2, ends) = self.__process(subtree)
108 midpoint.add_epsilon_transition(start2) 107 midpoint.add_epsilon_transition(start2)
109 midpoints.append(midpoint) 108 midpoints.append(midpoint)
110 109
111 return (start, ends + midpoints) 110 return (start, ends + midpoints)
112 111
113 def __cat(self, args): 112 def __cat(self, left_tree, right_tree):
114 (left, right) = (self.__process(args[0]), self.__process(args[1])) 113 (left, right) = (self.__process(left_tree), self.__process(right_tree))
115 self.__patch_ends(left[1], right[0]) 114 self.__patch_ends(left[1], right[0])
116 return (left[0], right[1]) 115 return (left[0], right[1])
117 116
118 def __key_state(self, key): 117 def __key_state(self, key):
119 state = self.__new_state() 118 state = self.__new_state()
120 state.add_unclosed_transition(key) 119 state.add_unclosed_transition(key)
121 return (state, [state]) 120 return (state, [state])
122 121
123 def __literal(self, args): 122 def __literal(self, char):
124 assert len(args) == 1
125 return self.__key_state( 123 return self.__key_state(
126 TransitionKey.single_char(self.__encoding, args[0])) 124 TransitionKey.single_char(self.__encoding, char))
127 125
128 def __class(self, args): 126 def __class(self, subtree):
129 assert len(args) == 1
130 return self.__key_state(TransitionKey.character_class( 127 return self.__key_state(TransitionKey.character_class(
131 self.__encoding, Term('CLASS', args[0]), self.__character_classes)) 128 self.__encoding, Term('CLASS', subtree), self.__character_classes))
132 129
133 def __not_class(self, args): 130 def __not_class(self, subtree):
134 assert len(args) == 1
135 return self.__key_state(TransitionKey.character_class( 131 return self.__key_state(TransitionKey.character_class(
136 self.__encoding, Term('NOT_CLASS', args[0]), self.__character_classes)) 132 self.__encoding, Term('NOT_CLASS', subtree), self.__character_classes))
137 133
138 def __any(self, args): 134 def __any(self):
139 return self.__key_state(TransitionKey.any(self.__encoding)) 135 return self.__key_state(TransitionKey.any(self.__encoding))
140 136
141 def __action(self, args): 137 def __action(self, subtree, action_term):
142 (start, ends) = self.__process(args[0]) 138 (start, ends) = self.__process(subtree)
143 action = Action.from_term(args[1]) 139 action = Action.from_term(action_term)
144 end = self.__new_state() 140 end = self.__new_state()
145 self.__patch_ends(ends, end) 141 self.__patch_ends(ends, end)
146 end.set_action(action) 142 end.set_action(action)
147 if action.match_action(): 143 if action.match_action():
148 global_end = self.__global_end() 144 global_end = self.__global_end()
149 end.add_epsilon_transition(global_end) 145 end.add_epsilon_transition(global_end)
150 return (start, [end]) 146 return (start, [end])
151 147
152 def __continue(self, args): 148 def __continue(self, subtree):
153 (start, ends) = self.__process(args[0]) 149 (start, ends) = self.__process(subtree)
154 state = self.__peek_state() 150 state = self.__peek_state()
155 if not state['start_node']: 151 if not state['start_node']:
156 state['start_node'] = self.__new_state() 152 state['start_node'] = self.__new_state()
157 self.__patch_ends(ends, state['start_node']) 153 self.__patch_ends(ends, state['start_node'])
158 return (start, []) 154 return (start, [])
159 155
160 def __unique_key(self, args): 156 def __unique_key(self, name):
161 return self.__key_state(TransitionKey.unique(args[0])) 157 return self.__key_state(TransitionKey.unique(name))
162 158
163 def __join(self, (graph, name, subgraph)): 159 def __join(self, graph, name, subgraph):
164 subgraphs = self.__peek_state()['subgraphs'] 160 subgraphs = self.__peek_state()['subgraphs']
165 if not name in subgraphs: 161 if not name in subgraphs:
166 subgraphs[name] = self.__nfa(subgraph) 162 subgraphs[name] = self.__nfa(subgraph)
167 (subgraph_start, subgraph_end, nodes_in_subgraph) = subgraphs[name] 163 (subgraph_start, subgraph_end, nodes_in_subgraph) = subgraphs[name]
168 (start, ends) = self.__process(graph) 164 (start, ends) = self.__process(graph)
169 self.__patch_ends(ends, subgraph_start) 165 self.__patch_ends(ends, subgraph_start)
170 if subgraph_end: 166 if subgraph_end:
171 end = self.__new_state() 167 end = self.__new_state()
172 subgraph_end.add_epsilon_transition(end) 168 subgraph_end.add_epsilon_transition(end)
173 return (start, [end]) 169 return (start, [end])
174 else: 170 else:
175 return (start, []) 171 return (start, [])
176 172
177 def __process(self, term): 173 def __process(self, term):
178 assert isinstance(term, Term) 174 assert isinstance(term, Term)
179 method = "_NfaBuilder__" + term.name().lower() 175 method = "_NfaBuilder__" + term.name().lower()
180 if not method in self.__operation_map: 176 if not method in self.__operation_map:
181 matches = filter(lambda (name, func): name == method, self.__members) 177 matches = filter(lambda (name, func): name == method, self.__members)
182 assert len(matches) == 1 178 assert len(matches) == 1
183 self.__operation_map[method] = matches[0][1] 179 self.__operation_map[method] = matches[0][1]
184 return self.__operation_map[method](term.args()) 180 return self.__operation_map[method](*term.args())
185 181
186 def __patch_ends(self, ends, new_end): 182 def __patch_ends(self, ends, new_end):
187 for end in ends: 183 for end in ends:
188 end.close(new_end) 184 end.close(new_end)
189 185
190 def __push_state(self): 186 def __push_state(self):
191 self.__states.append({ 187 self.__states.append({
192 'start_node' : None, 188 'start_node' : None,
193 'subgraphs' : {}, 189 'subgraphs' : {},
194 'unpatched_ends' : [], 190 'unpatched_ends' : [],
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 295
300 __modifer_map = { 296 __modifer_map = {
301 '+': 'ONE_OR_MORE', 297 '+': 'ONE_OR_MORE',
302 '?': 'ZERO_OR_ONE', 298 '?': 'ZERO_OR_ONE',
303 '*': 'ZERO_OR_MORE', 299 '*': 'ZERO_OR_MORE',
304 } 300 }
305 301
306 @staticmethod 302 @staticmethod
307 def apply_modifier(modifier, term): 303 def apply_modifier(modifier, term):
308 return Term(NfaBuilder.__modifer_map[modifier], term) 304 return Term(NfaBuilder.__modifer_map[modifier], term)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698