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

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

Issue 139853014: Experimental parser: revert read_cursor (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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 dfa = rule_processor.default_automata().dfa() 47 dfa = rule_processor.default_automata().dfa()
48 self.__dfa = dfa 48 self.__dfa = dfa
49 self.__default_action = rule_processor.default_action 49 self.__default_action = rule_processor.default_action
50 self.__debug_print = debug_print 50 self.__debug_print = debug_print
51 self.__start_node_number = self.__dfa.start_state().node_number() 51 self.__start_node_number = self.__dfa.start_state().node_number()
52 self.__log = log 52 self.__log = log
53 self.__inline = inline 53 self.__inline = inline
54 self.__switching = switching 54 self.__switching = switching
55 self.__jump_table = [] 55 self.__jump_table = []
56 56
57 __jump_labels = ['state_entry', 'after_entry_code', 'before_match'] 57 __jump_labels = ['state_entry', 'after_entry_code']
58 58
59 @staticmethod 59 @staticmethod
60 def __transform_state(encoding, state): 60 def __transform_state(encoding, state):
61 # action data 61 # action data
62 action = state.action() 62 action = state.action()
63 entry_action = None if not action else action.entry_action() 63 entry_action = None if not action else action.entry_action()
64 match_action = None if not action else action.match_action() 64 match_action = None if not action else action.match_action()
65 # generate ordered transitions 65 # generate ordered transitions
66 transitions = map(lambda (k, v) : (k, v.node_number()), 66 transitions = map(lambda (k, v) : (k, v.node_number()),
67 state.transitions().items()) 67 state.transitions().items())
68 def cmp(left, right): 68 def cmp(left, right):
69 return TransitionKey.canonical_compare(left[0], right[0]) 69 return TransitionKey.canonical_compare(left[0], right[0])
70 transitions = sorted(transitions, cmp) 70 transitions = sorted(transitions, cmp)
71 # map transition keys to disjoint ranges and collect stats 71 # map transition keys to disjoint ranges and collect stats
72 disjoint_keys = [] 72 disjoint_keys = []
73 unique_transitions = {} 73 unique_transitions = {}
74 old_transitions = transitions 74 old_transitions = transitions
75 transitions = [] 75 transitions = []
76 (class_keys, distinct_keys, ranges) = (0, 0, 0) 76 (class_keys, distinct_keys, ranges) = (0, 0, 0)
77 zero_transition = None
77 for key, transition_id in old_transitions: 78 for key, transition_id in old_transitions:
78 keys = [] 79 keys = []
79 for (t, r) in key.range_iter(encoding): 80 for (t, r) in key.range_iter(encoding):
80 if t == 'CLASS': 81 if t == 'CLASS':
81 class_keys += 1 82 class_keys += 1
82 keys.append((t, r)) 83 keys.append((t, r))
83 elif t == 'PRIMARY_RANGE': 84 elif t == 'PRIMARY_RANGE':
84 distinct_keys += r[1] - r[0] + 1 85 distinct_keys += r[1] - r[0] + 1
85 ranges += 1 86 ranges += 1
87 # split 0 out of range, don't bother updating stats
88 assert r[0] >= 0
89 if r[0] == 0:
90 assert zero_transition == None
91 zero_transition = transition_id
92 if r[0] == r[1]:
93 continue
94 r = (r[0] + 1, r[1])
86 keys.append((t, r)) 95 keys.append((t, r))
87 elif t == 'UNIQUE': 96 elif t == 'UNIQUE':
88 assert r == 'no_match' or r == 'eos' 97 assert r == 'no_match' or r == 'eos'
89 assert r not in unique_transitions 98 assert r not in unique_transitions
90 unique_transitions[r] = transition_id 99 unique_transitions[r] = transition_id
91 else: 100 else:
92 raise Exception() 101 raise Exception()
93 if keys: 102 if keys:
94 transitions.append((keys, transition_id)) 103 transitions.append((keys, transition_id))
104 # delay zero transition until last
105 if zero_transition != None:
106 transitions.append(([('PRIMARY_RANGE', (0, 0))], transition_id))
95 return { 107 return {
96 'node_number' : None, 108 'node_number' : None,
97 'original_node_number' : state.node_number(), 109 'original_node_number' : state.node_number(),
98 'transitions' : transitions, 110 'transitions' : transitions,
99 # flags for code generator 111 # flags for code generator
100 'can_elide_read' : len(transitions) == 0, 112 'can_elide_read' : len(transitions) == 0,
101 'is_eos_handler' : False, 113 'is_eos_handler' : False,
102 'inline' : None, 114 'inline' : False,
103 'must_not_inline' : False, 115 'must_not_inline' : False,
104 # transitions for code generator 116 # transitions for code generator
105 'if_transitions' : [], 117 'if_transitions' : [],
106 'switch_transitions' : [], 118 'switch_transitions' : [],
107 'deferred_transitions' : [], 119 'deferred_transitions' : [],
108 'unique_transitions' : unique_transitions, 120 'unique_transitions' : unique_transitions,
109 # state actions 121 # state actions
110 'entry_action' : entry_action, 122 'entry_action' : entry_action,
111 'match_action' : match_action, 123 'match_action' : match_action,
112 # statistics for states 124 # statistics for states
113 'class_keys' : class_keys, 125 'class_keys' : class_keys,
114 'distinct_keys' : distinct_keys, 126 'distinct_keys' : distinct_keys,
115 'ranges' : ranges, 127 'ranges' : ranges,
116 # record of which entry points will be needed 128 # record of which entry points will be needed
117 'entry_points' : {k : False for k in CodeGenerator.__jump_labels} 129 'entry_points' : {k : False for k in CodeGenerator.__jump_labels}
118 } 130 }
119 131
120 def __register_jump(self, node_id, label): 132 def __register_jump(self, node_id, label):
121 if label != 'inline': 133 if label != 'inline':
122 assert label in CodeGenerator.__jump_labels 134 assert label in CodeGenerator.__jump_labels
123 state = self.__dfa_states[node_id]['entry_points'][label] = True 135 state = self.__dfa_states[node_id]['entry_points'][label] = True
124 self.__jump_table.append((node_id, label)) 136 self.__jump_table.append((node_id, label))
125 return len(self.__jump_table) - 1 137 return len(self.__jump_table) - 1
126 138
127 def __set_inline(self, count, state): 139 def __set_inline(self, count, state):
128 assert state['inline'] == None
129 inline = False 140 inline = False
130 if state['must_not_inline']: 141 if state['must_not_inline']:
131 inline = False 142 inline = False
132 # inline terminal states 143 # inline terminal states
133 elif not state['transitions']: 144 elif not state['transitions']:
134 inline = True 145 inline = True
135 # inline next to terminal states with 1 or 2 transitions 146 # inline next to terminal states with 1 or 2 transitions
136 elif state['distinct_keys'] < 3 and state['class_keys'] == 0: 147 elif state['distinct_keys'] < 3 and state['class_keys'] == 0:
137 inline = True 148 inline = True
138 # ensure state terminates in 1 step 149 # ensure state terminates in 1 step
(...skipping 14 matching lines...) Expand all
153 switch_transitions = [] 164 switch_transitions = []
154 deferred_transitions = [] 165 deferred_transitions = []
155 for (ranges, node_id) in state['transitions']: 166 for (ranges, node_id) in state['transitions']:
156 i = [] 167 i = []
157 s = [] 168 s = []
158 d = [] 169 d = []
159 for r in ranges: 170 for r in ranges:
160 # all class checks will be deferred to after all other checks 171 # all class checks will be deferred to after all other checks
161 if r[0] == 'CLASS': 172 if r[0] == 'CLASS':
162 d.append(r) 173 d.append(r)
163 elif no_switch: 174 # zero must assigned to an if check because of eos check
175 elif no_switch or (r[1][0] == 0):
164 i.append(r) 176 i.append(r)
165 else: 177 else:
166 s.append(r[1]) 178 s.append(r[1])
167 if i: 179 if i:
168 if_transitions.append((i, node_id)) 180 if_transitions.append((i, node_id))
169 if s: 181 if s:
170 switch_transitions.append((s, node_id)) 182 switch_transitions.append((s, node_id))
171 if d: 183 if d:
172 deferred_transitions.append((d, node_id)) 184 deferred_transitions.append((d, node_id))
173 state['if_transitions'] = if_transitions 185 state['if_transitions'] = if_transitions
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 else: 359 else:
348 assert not target_id in inline_mapping 360 assert not target_id in inline_mapping
349 return (key, self.__register_jump(target_id, jump_type)) 361 return (key, self.__register_jump(target_id, jump_type))
350 for name in transition_names: 362 for name in transition_names:
351 state[name] = map(generate_jump, state[name]) 363 state[name] = map(generate_jump, state[name])
352 if 'eos' in state['unique_transitions']: 364 if 'eos' in state['unique_transitions']:
353 # eos state is not inlined 365 # eos state is not inlined
354 eos_state_id = state['unique_transitions']['eos'] 366 eos_state_id = state['unique_transitions']['eos']
355 jump = self.__register_jump(eos_state_id, 'state_entry') 367 jump = self.__register_jump(eos_state_id, 'state_entry')
356 state['unique_transitions']['eos'] = jump 368 state['unique_transitions']['eos'] = jump
357 elif state['transitions']:
358 jump = self.__register_jump(state_id, 'before_match')
359 state['jump_before_match'] = jump
360 # now rewrite all nodes created 369 # now rewrite all nodes created
361 nodes_created = len(inline_mapping) - len(inline_mapping_in) 370 nodes_created = len(inline_mapping) - len(inline_mapping_in)
362 assert len(self.__dfa_states) == ( 371 assert len(self.__dfa_states) == (
363 end_offset + total_nodes_created + nodes_created) 372 end_offset + total_nodes_created + nodes_created)
364 if nodes_created == 0: 373 if nodes_created == 0:
365 continue 374 continue
366 created = self.__rewrite_transitions_to_jumps( 375 created = self.__rewrite_transitions_to_jumps(
367 end_offset + total_nodes_created, nodes_created, inline_mapping) 376 end_offset + total_nodes_created, nodes_created, inline_mapping)
368 total_nodes_created += nodes_created + created 377 total_nodes_created += nodes_created + created
369 return total_nodes_created 378 return total_nodes_created
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 418
410 return template.render( 419 return template.render(
411 start_node_number = 0, 420 start_node_number = 0,
412 debug_print = self.__debug_print, 421 debug_print = self.__debug_print,
413 default_action = default_action, 422 default_action = default_action,
414 dfa_states = dfa_states, 423 dfa_states = dfa_states,
415 jump_table = self.__jump_table, 424 jump_table = self.__jump_table,
416 encoding = encoding.name(), 425 encoding = encoding.name(),
417 char_type = char_type, 426 char_type = char_type,
418 upper_bound = encoding.primary_range()[1]) 427 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