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

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

Issue 77353004: Experimental parser: more inlining (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 | « 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 transitions = sorted(transitions, cmp) 107 transitions = sorted(transitions, cmp)
108 # map transition keys to disjoint ranges 108 # map transition keys to disjoint ranges
109 disjoint_keys = {'value' : []} 109 disjoint_keys = {'value' : []}
110 def f((key, state)): 110 def f((key, state)):
111 ranges = list(key.range_iter()) 111 ranges = list(key.range_iter())
112 disjoint_keys['value'] += ranges 112 disjoint_keys['value'] += ranges
113 return (ranges, state) 113 return (ranges, state)
114 transitions = map(f, transitions) 114 transitions = map(f, transitions)
115 disjoint_keys = sorted(disjoint_keys['value'], CodeGenerator.__range_cmp) 115 disjoint_keys = sorted(disjoint_keys['value'], CodeGenerator.__range_cmp)
116 # dictionary object representing state 116 # dictionary object representing state
117 (class_keys, distinct_keys, ranges) = (0, 0, 0)
118 for (t, r) in disjoint_keys:
119 if t == 'CLASS':
120 class_keys += 1
121 elif t == 'LATIN_1':
122 distinct_keys += r[1] - r[0] + 1
123 ranges += 1
124 else:
125 raise Exception()
117 return { 126 return {
118 'node_number' : state.node_number(), 127 'node_number' : state.node_number(),
119 'original_node_number' : state.node_number(), 128 'original_node_number' : state.node_number(),
120 'transitions' : transitions, 129 'transitions' : transitions,
121 'switch_transitions' : [], 130 'switch_transitions' : [],
122 'disjoint_keys' : disjoint_keys, 131 'disjoint_keys' : disjoint_keys,
123 'inline' : None, 132 'inline' : None,
124 'depth' : None, 133 'depth' : None,
125 'action' : action, 134 'action' : action,
126 'entry_action' : entry_action, 135 'entry_action' : entry_action,
127 'match_action' : match_action, 136 'match_action' : match_action,
137 'class_keys' : class_keys,
138 'distinct_keys' : distinct_keys,
139 'ranges' : ranges
128 } 140 }
129 141
130 @staticmethod 142 @staticmethod
131 def __compute_depths(node_number, depth, id_map): 143 def __compute_depths(node_number, depth, id_map):
132 state = id_map[node_number] 144 state = id_map[node_number]
133 if state['depth'] != None: 145 if state['depth'] != None:
134 return 146 return
135 state['depth'] = depth 147 state['depth'] = depth
136 for (k, transition_node) in state['transitions']: 148 for (k, transition_node) in state['transitions']:
137 CodeGenerator.__compute_depths(transition_node, depth + 1, id_map) 149 CodeGenerator.__compute_depths(transition_node, depth + 1, id_map)
138 150
139 @staticmethod 151 def __set_inline(self, count, state):
140 def __set_inline(count, state):
141 assert state['inline'] == None 152 assert state['inline'] == None
142 inline = False 153 inline = False
154 # inline terminal states
143 if not state['transitions']: 155 if not state['transitions']:
144 inline = True 156 inline = True
145 # TODO add in 1 or 2 element if blocks 157 # inline next to terminal states with 1 or 2 transitions
158 elif state['distinct_keys'] < 3 and state['class_keys'] == 0:
159 inline = True
160 # ensure state terminates in 1 step
161 for key, state_id in state['transitions']:
162 if self.__dfa_states[state_id]['transitions']:
163 inline = False
164 break
146 state['inline'] = inline 165 state['inline'] = inline
147 return count + 1 if inline else count 166 return count + 1 if inline else count
148 167
149 @staticmethod 168 @staticmethod
150 def __split_transitions(split_count, state): 169 def __split_transitions(split_count, state):
151 '''Goes through the transitions for 'state' and decides which of them should 170 '''Goes through the transitions for 'state' and decides which of them should
152 use the if statement and which should use the switch statement.''' 171 use the if statement and which should use the switch statement.'''
153 assert not state['switch_transitions'] 172 assert not state['switch_transitions']
154 (class_keys, distinct_keys, ranges) = (0, 0, 0) 173 (distinct_keys, ranges) = (state['distinct_keys'], state['ranges'])
155 for (t, r) in state['disjoint_keys']:
156 if t == 'CLASS':
157 class_keys += 1
158 elif t == 'LATIN_1':
159 distinct_keys += r[1] - r[0] + 1
160 ranges += 1
161 else:
162 raise Exception()
163 if distinct_keys <= 7 or float(distinct_keys)/float(ranges) >= 7.0: 174 if distinct_keys <= 7 or float(distinct_keys)/float(ranges) >= 7.0:
164 return split_count 175 return split_count
165 switch_transitions = [] 176 switch_transitions = []
166 if_transitions = [] 177 if_transitions = []
167 for (ranges, node_id) in state['transitions']: 178 for (ranges, node_id) in state['transitions']:
168 i = [] 179 i = []
169 s = [] 180 s = []
170 for r in ranges: 181 for r in ranges:
171 if r[0] == 'CLASS': 182 if r[0] == 'CLASS':
172 i.append(r) 183 i.append(r)
(...skipping 16 matching lines...) Expand all
189 dfa_states = sorted(dfa_states, cmp=self.__state_cmp) 200 dfa_states = sorted(dfa_states, cmp=self.__state_cmp)
190 # remap all node numbers 201 # remap all node numbers
191 for i, state in enumerate(dfa_states): 202 for i, state in enumerate(dfa_states):
192 state['node_number'] = i 203 state['node_number'] = i
193 def f((key, original_node_number)): 204 def f((key, original_node_number)):
194 return (key, id_map[original_node_number]['node_number']) 205 return (key, id_map[original_node_number]['node_number'])
195 for state in dfa_states: 206 for state in dfa_states:
196 state['transitions'] = map(f, state['transitions']) 207 state['transitions'] = map(f, state['transitions'])
197 assert id_map[self.__start_node_number]['node_number'] == 0 208 assert id_map[self.__start_node_number]['node_number'] == 0
198 assert len(dfa_states) == self.__dfa.node_count() 209 assert len(dfa_states) == self.__dfa.node_count()
210 # store states
211 self.__dfa_states = dfa_states
199 # set nodes to inline 212 # set nodes to inline
200 if self.__inline: 213 if self.__inline:
201 inlined = reduce(CodeGenerator.__set_inline, dfa_states, 0) 214 inlined = reduce(self.__set_inline, dfa_states, 0)
202 if self.__log: 215 if self.__log:
203 print "%s states inlined" % inlined 216 print "%s states inlined" % inlined
204 elif self.__log: 217 elif self.__log:
205 print "no inlining" 218 print "no inlining"
206 # split transitions 219 # split transitions
207 if self.__switching: 220 if self.__switching:
208 switched = reduce(CodeGenerator.__split_transitions, dfa_states, 0) 221 switched = reduce(CodeGenerator.__split_transitions, dfa_states, 0)
209 if self.__log: 222 if self.__log:
210 print "%s states use switch (instead of if)" % switched 223 print "%s states use switch (instead of if)" % switched
211 elif self.__log: 224 elif self.__log:
212 print "no switching" 225 print "no switching"
213 # store states
214 self.__dfa_states = dfa_states
215 226
216 def process(self): 227 def process(self):
217 228
218 self.__canonicalize_traversal() 229 self.__canonicalize_traversal()
219 230
220 dfa_states = self.__dfa_states 231 dfa_states = self.__dfa_states
221 232
222 default_action = self.__default_action 233 default_action = self.__default_action
223 assert(default_action and default_action.match_action()) 234 assert(default_action and default_action.match_action())
224 default_action = default_action.match_action() 235 default_action = default_action.match_action()
225 236
226 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 237 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
227 template_env = jinja2.Environment( 238 template_env = jinja2.Environment(
228 loader = jinja2.PackageLoader('lexer_generator', '.'), 239 loader = jinja2.PackageLoader('lexer_generator', '.'),
229 undefined = jinja2.StrictUndefined) 240 undefined = jinja2.StrictUndefined)
230 template = template_env.get_template('code_generator.jinja') 241 template = template_env.get_template('code_generator.jinja')
231 242
232 return template.render( 243 return template.render(
233 start_node_number = 0, 244 start_node_number = 0,
234 debug_print = self.__debug_print, 245 debug_print = self.__debug_print,
235 default_action = default_action, 246 default_action = default_action,
236 dfa_states = dfa_states) 247 dfa_states = dfa_states)
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