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

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

Issue 80513003: Experimental parser: add everything_else class (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/code_generator.jinja ('k') | tools/lexer_generator/transition_keys.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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 elif t == 'LATIN_1': 123 elif t == 'LATIN_1':
124 distinct_keys += r[1] - r[0] + 1 124 distinct_keys += r[1] - r[0] + 1
125 ranges += 1 125 ranges += 1
126 else: 126 else:
127 raise Exception() 127 raise Exception()
128 return { 128 return {
129 'node_number' : state.node_number(), 129 'node_number' : state.node_number(),
130 'original_node_number' : state.node_number(), 130 'original_node_number' : state.node_number(),
131 'transitions' : transitions, 131 'transitions' : transitions,
132 'switch_transitions' : [], 132 'switch_transitions' : [],
133 'deferred_transitions' : [],
133 'disjoint_keys' : disjoint_keys, 134 'disjoint_keys' : disjoint_keys,
134 'inline' : None, 135 'inline' : None,
135 'depth' : None, 136 'depth' : None,
136 'action' : action, 137 'action' : action,
137 'entry_action' : entry_action, 138 'entry_action' : entry_action,
138 'match_action' : match_action, 139 'match_action' : match_action,
139 'class_keys' : class_keys, 140 'class_keys' : class_keys,
140 'distinct_keys' : distinct_keys, 141 'distinct_keys' : distinct_keys,
141 'ranges' : ranges 142 'ranges' : ranges
142 } 143 }
(...skipping 17 matching lines...) Expand all
160 elif state['distinct_keys'] < 3 and state['class_keys'] == 0: 161 elif state['distinct_keys'] < 3 and state['class_keys'] == 0:
161 inline = True 162 inline = True
162 # ensure state terminates in 1 step 163 # ensure state terminates in 1 step
163 for key, state_id in state['transitions']: 164 for key, state_id in state['transitions']:
164 if self.__dfa_states[state_id]['transitions']: 165 if self.__dfa_states[state_id]['transitions']:
165 inline = False 166 inline = False
166 break 167 break
167 state['inline'] = inline 168 state['inline'] = inline
168 return count + 1 if inline else count 169 return count + 1 if inline else count
169 170
170 @staticmethod 171 def __split_transitions(self, split_count, state):
171 def __split_transitions(split_count, state):
172 '''Goes through the transitions for 'state' and decides which of them should 172 '''Goes through the transitions for 'state' and decides which of them should
173 use the if statement and which should use the switch statement.''' 173 use the if statement and which should use the switch statement.'''
174 assert not state['switch_transitions'] 174 assert not state['switch_transitions']
175 (distinct_keys, ranges) = (state['distinct_keys'], state['ranges']) 175 (distinct_keys, ranges) = (state['distinct_keys'], state['ranges'])
176 if distinct_keys <= 7 or float(distinct_keys)/float(ranges) >= 7.0: 176 no_switch = distinct_keys <= 7 or float(distinct_keys)/float(ranges) >= 7.0
177 return split_count 177 if_transitions = []
178 switch_transitions = [] 178 switch_transitions = []
179 if_transitions = [] 179 deferred_transitions = []
180 for (ranges, node_id) in state['transitions']: 180 for (ranges, node_id) in state['transitions']:
181 i = [] 181 i = []
182 s = [] 182 s = []
183 d = []
183 for r in ranges: 184 for r in ranges:
185 # all class checks will be deferred to after all other checks
184 if r[0] == 'CLASS': 186 if r[0] == 'CLASS':
187 d.append(r)
188 elif no_switch:
185 i.append(r) 189 i.append(r)
186 else: 190 else:
187 s.append(r[1]) 191 s.append(r[1])
188 if i: 192 if i:
189 if_transitions.append((i, node_id)) 193 if_transitions.append((i, node_id))
190 if s: 194 if s:
191 switch_transitions.append((s, node_id)) 195 switch_transitions.append((s, node_id))
196 if d:
197 deferred_transitions.append((d, node_id))
192 state['transitions'] = if_transitions 198 state['transitions'] = if_transitions
193 state['switch_transitions'] = switch_transitions 199 state['switch_transitions'] = switch_transitions
194 return split_count + 1 200 state['deferred_transitions'] = deferred_transitions
201 return split_count + (0 if no_switch else 1)
195 202
196 def __canonicalize_traversal(self): 203 def __canonicalize_traversal(self):
197 dfa_states = [] 204 dfa_states = []
198 self.__dfa.visit_all_states(lambda state, acc: dfa_states.append(state)) 205 self.__dfa.visit_all_states(lambda state, acc: dfa_states.append(state))
199 dfa_states = map(CodeGenerator.__transform_state, dfa_states) 206 dfa_states = map(CodeGenerator.__transform_state, dfa_states)
200 id_map = {x['original_node_number'] : x for x in dfa_states} 207 id_map = {x['original_node_number'] : x for x in dfa_states}
201 CodeGenerator.__compute_depths(self.__start_node_number, 1, id_map) 208 CodeGenerator.__compute_depths(self.__start_node_number, 1, id_map)
202 dfa_states = sorted(dfa_states, cmp=self.__state_cmp) 209 dfa_states = sorted(dfa_states, cmp=self.__state_cmp)
203 # remap all node numbers 210 # remap all node numbers
204 for i, state in enumerate(dfa_states): 211 for i, state in enumerate(dfa_states):
205 state['node_number'] = i 212 state['node_number'] = i
206 def f((key, original_node_number)): 213 def f((key, original_node_number)):
207 return (key, id_map[original_node_number]['node_number']) 214 return (key, id_map[original_node_number]['node_number'])
208 for state in dfa_states: 215 for state in dfa_states:
209 state['transitions'] = map(f, state['transitions']) 216 state['transitions'] = map(f, state['transitions'])
210 assert id_map[self.__start_node_number]['node_number'] == 0 217 assert id_map[self.__start_node_number]['node_number'] == 0
211 assert len(dfa_states) == self.__dfa.node_count() 218 assert len(dfa_states) == self.__dfa.node_count()
212 # store states 219 # store states
213 self.__dfa_states = dfa_states 220 self.__dfa_states = dfa_states
214 # set nodes to inline 221 # set nodes to inline
215 if self.__inline: 222 if self.__inline:
216 inlined = reduce(self.__set_inline, dfa_states, 0) 223 inlined = reduce(self.__set_inline, dfa_states, 0)
217 if self.__log: 224 if self.__log:
218 print "%s states inlined" % inlined 225 print "%s states inlined" % inlined
219 elif self.__log: 226 elif self.__log:
220 print "no inlining" 227 print "no inlining"
221 # split transitions 228 # split transitions
222 if self.__switching: 229 switched = reduce(self.__split_transitions, dfa_states, 0)
223 switched = reduce(CodeGenerator.__split_transitions, dfa_states, 0) 230 if self.__log:
224 if self.__log: 231 print "%s states use switch (instead of if)" % switched
225 print "%s states use switch (instead of if)" % switched
226 elif self.__log:
227 print "no switching"
228 232
229 def process(self): 233 def process(self):
230 234
231 self.__canonicalize_traversal() 235 self.__canonicalize_traversal()
232 236
233 dfa_states = self.__dfa_states 237 dfa_states = self.__dfa_states
234 238
235 default_action = self.__default_action 239 default_action = self.__default_action
236 assert(default_action and default_action.match_action()) 240 assert(default_action and default_action.match_action())
237 default_action = default_action.match_action() 241 default_action = default_action.match_action()
(...skipping 10 matching lines...) Expand all
248 char_type = 'uint16_t' 252 char_type = 'uint16_t'
249 else: 253 else:
250 raise Exception('Unsupported encoding %s' % encoding) 254 raise Exception('Unsupported encoding %s' % encoding)
251 return template.render( 255 return template.render(
252 start_node_number = 0, 256 start_node_number = 0,
253 debug_print = self.__debug_print, 257 debug_print = self.__debug_print,
254 default_action = default_action, 258 default_action = default_action,
255 dfa_states = dfa_states, 259 dfa_states = dfa_states,
256 encoding = self.__encoding, 260 encoding = self.__encoding,
257 char_type = char_type) 261 char_type = char_type)
OLDNEW
« no previous file with comments | « tools/lexer_generator/code_generator.jinja ('k') | tools/lexer_generator/transition_keys.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698