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

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

Issue 145623002: Experimental parser: cleanup deferred transitions (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 11 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 | « tools/lexer_generator/code_generator.jinja ('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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 'transitions' : transitions, 98 'transitions' : transitions,
99 # flags for code generator 99 # flags for code generator
100 'can_elide_read' : len(transitions) == 0, 100 'can_elide_read' : len(transitions) == 0,
101 'is_eos_handler' : False, 101 'is_eos_handler' : False,
102 'inline' : None, 102 'inline' : None,
103 'must_not_inline' : False, 103 'must_not_inline' : False,
104 # transitions for code generator 104 # transitions for code generator
105 'if_transitions' : [], 105 'if_transitions' : [],
106 'switch_transitions' : [], 106 'switch_transitions' : [],
107 'deferred_transitions' : [], 107 'deferred_transitions' : [],
108 'long_char_transitions' : [],
109 'unique_transitions' : unique_transitions, 108 'unique_transitions' : unique_transitions,
110 # state actions 109 # state actions
111 'entry_action' : entry_action, 110 'entry_action' : entry_action,
112 'match_action' : match_action, 111 'match_action' : match_action,
113 # statistics for states 112 # statistics for states
114 'class_keys' : class_keys, 113 'class_keys' : class_keys,
115 'distinct_keys' : distinct_keys, 114 'distinct_keys' : distinct_keys,
116 'ranges' : ranges, 115 'ranges' : ranges,
117 # record of which entry points will be needed 116 # record of which entry points will be needed
118 'entry_points' : {k : False for k in CodeGenerator.__jump_labels} 117 'entry_points' : {k : False for k in CodeGenerator.__jump_labels}
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 return split_count + (0 if no_switch else 1) 176 return split_count + (0 if no_switch else 1)
178 177
179 __call_map = { 178 __call_map = {
180 'non_primary_whitespace' : 'IsWhiteSpaceNotLineTerminator', 179 'non_primary_whitespace' : 'IsWhiteSpaceNotLineTerminator',
181 'non_primary_letter' : 'IsLetter', 180 'non_primary_letter' : 'IsLetter',
182 'non_primary_identifier_part_not_letter' : 'IsIdentifierPartNotLetter', 181 'non_primary_identifier_part_not_letter' : 'IsIdentifierPartNotLetter',
183 'non_primary_line_terminator' : 'IsLineTerminator', 182 'non_primary_line_terminator' : 'IsLineTerminator',
184 } 183 }
185 184
186 def __rewrite_deferred_transitions(self, state): 185 def __rewrite_deferred_transitions(self, state):
187 assert not state['long_char_transitions']
188 transitions = state['deferred_transitions'] 186 transitions = state['deferred_transitions']
189 if not transitions: 187 if not transitions:
190 return 188 return
191 encoding = self.__dfa.encoding() 189 encoding = self.__dfa.encoding()
192 bom = 'byte_order_mark' 190 bom = 'byte_order_mark'
193 catch_all = 'non_primary_everything_else' 191 catch_all = 'non_primary_everything_else'
194 all_classes = set(encoding.class_name_iter()) 192 all_classes = set(encoding.class_name_iter())
195 fast_classes = set([]) 193 call_classes = all_classes - set([bom, catch_all])
196 call_classes = all_classes - fast_classes - set([bom, catch_all])
197 def remap_transition(class_name): 194 def remap_transition(class_name):
198 if class_name in call_classes: 195 if class_name in call_classes:
199 return ('LONG_CHAR_CLASS', 'call', self.__call_map[class_name]) 196 return ('LONG_CHAR_CLASS', 'call', self.__call_map[class_name])
200 if class_name == bom: 197 if class_name == bom:
201 return ('LONG_CHAR_CLASS', class_name) 198 return ('LONG_CHAR_CLASS', class_name)
202 raise Exception(class_name) 199 raise Exception(class_name)
203 fast_transitions = []
204 long_class_transitions = [] 200 long_class_transitions = []
205 long_class_map = {} 201 long_class_map = {}
206 catchall_transition = None 202 catchall_transition = None
207 # loop through and remove catch_all_transitions 203 # loop through and remove catch_all_transitions
208 for (classes, transition_node_id) in transitions: 204 for (classes, transition_node_id) in transitions:
209 ft = []
210 lct = [] 205 lct = []
211 has_catch_all = False 206 has_catch_all = False
212 for (class_type, class_name) in classes: 207 for (class_type, class_name) in classes:
213 if class_name in fast_classes: 208 assert not class_name in long_class_map
214 ft.append((class_type, class_name)) 209 long_class_map[class_name] = transition_node_id
210 if class_name == catch_all:
211 assert not has_catch_all
212 assert catchall_transition == None
213 has_catch_all = True
215 else: 214 else:
216 assert not class_name in long_class_map 215 lct.append(remap_transition(class_name))
217 long_class_map[class_name] = transition_node_id
218 if class_name == catch_all:
219 assert not has_catch_all
220 assert catchall_transition == None
221 has_catch_all = True
222 else:
223 lct.append(remap_transition(class_name))
224 if ft:
225 fast_transitions.append((ft, transition_node_id))
226 if has_catch_all: 216 if has_catch_all:
227 catchall_transition = (lct, transition_node_id) 217 catchall_transition = (lct, transition_node_id)
228 elif lct: 218 elif lct:
229 long_class_transitions.append((lct, transition_node_id)) 219 long_class_transitions.append((lct, transition_node_id))
230 # all transitions are fast
231 if not long_class_map:
232 return
233 if catchall_transition: 220 if catchall_transition:
234 catchall_transitions = all_classes - fast_classes 221 catchall_transitions = all_classes
235 for class_name in long_class_map.iterkeys(): 222 for class_name in long_class_map.iterkeys():
236 catchall_transitions.remove(class_name) 223 catchall_transitions.remove(class_name)
237 assert not catchall_transitions, "class inversion not unimplemented" 224 assert not catchall_transitions, "class inversion not unimplemented"
238 # split deferred transitions
239 state['deferred_transitions'] = fast_transitions
240 if catchall_transition: 225 if catchall_transition:
241 catchall_transition = [ 226 catchall_transition = [
242 ([('LONG_CHAR_CLASS', 'catch_all')], catchall_transition[1])] 227 ([('LONG_CHAR_CLASS', 'catch_all')], catchall_transition[1])]
243 else: 228 else:
244 catchall_transition = [] 229 catchall_transition = []
245 state['long_char_transitions'] = (long_class_transitions + 230 state['deferred_transitions'] = (long_class_transitions +
246 catchall_transition) # must be last 231 catchall_transition) # must be last
247 232
248 @staticmethod 233 @staticmethod
249 def __reorder(current_node_number, id_map, dfa_states): 234 def __reorder(current_node_number, id_map, dfa_states):
250 current_node = id_map[current_node_number] 235 current_node = id_map[current_node_number]
251 if current_node['node_number'] != None: 236 if current_node['node_number'] != None:
252 return 237 return
253 current_node['node_number'] = len(dfa_states) 238 current_node['node_number'] = len(dfa_states)
254 dfa_states.append(current_node) 239 dfa_states.append(current_node)
255 for (key, node_number) in current_node['transitions']: 240 for (key, node_number) in current_node['transitions']:
256 CodeGenerator.__reorder(node_number, id_map, dfa_states) 241 CodeGenerator.__reorder(node_number, id_map, dfa_states)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 state['inline'] = None 315 state['inline'] = None
331 # clear entry points 316 # clear entry points
332 state['entry_points'] = {k : False for k in CodeGenerator.__jump_labels} 317 state['entry_points'] = {k : False for k in CodeGenerator.__jump_labels}
333 return state['node_number'] 318 return state['node_number']
334 319
335 def __rewrite_transitions_to_jumps(self, start_id, count, inline_mapping_in): 320 def __rewrite_transitions_to_jumps(self, start_id, count, inline_mapping_in):
336 # order here should match the order of code generation 321 # order here should match the order of code generation
337 transition_names = [ 322 transition_names = [
338 'switch_transitions', 323 'switch_transitions',
339 'if_transitions', 324 'if_transitions',
340 'long_char_transitions',
341 'deferred_transitions'] 325 'deferred_transitions']
342 end_offset = start_id + count 326 end_offset = start_id + count
343 assert len(self.__dfa_states) == end_offset 327 assert len(self.__dfa_states) == end_offset
344 total_nodes_created = 0 328 total_nodes_created = 0
345 for state_id in range(start_id, end_offset): 329 for state_id in range(start_id, end_offset):
346 state = self.__dfa_states[state_id] 330 state = self.__dfa_states[state_id]
347 # this will be ignored during code generation, 331 # this will be ignored during code generation,
348 # and it's needed as a template, so don't rewrite 332 # and it's needed as a template, so don't rewrite
349 if state['inline'] == True: 333 if state['inline'] == True:
350 continue 334 continue
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 409
426 return template.render( 410 return template.render(
427 start_node_number = 0, 411 start_node_number = 0,
428 debug_print = self.__debug_print, 412 debug_print = self.__debug_print,
429 default_action = default_action, 413 default_action = default_action,
430 dfa_states = dfa_states, 414 dfa_states = dfa_states,
431 jump_table = self.__jump_table, 415 jump_table = self.__jump_table,
432 encoding = encoding.name(), 416 encoding = encoding.name(),
433 char_type = char_type, 417 char_type = char_type,
434 upper_bound = encoding.primary_range()[1]) 418 upper_bound = encoding.primary_range()[1])
OLDNEW
« no previous file with comments | « tools/lexer_generator/code_generator.jinja ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698