| OLD | NEW |
| 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 assert state['inline'] == None | 141 assert state['inline'] == None |
| 142 inline = False | 142 inline = False |
| 143 if not state['transitions']: | 143 if not state['transitions']: |
| 144 inline = True | 144 inline = True |
| 145 # TODO add in 1 or 2 element if blocks | 145 # TODO add in 1 or 2 element if blocks |
| 146 state['inline'] = inline | 146 state['inline'] = inline |
| 147 return count + 1 if inline else count | 147 return count + 1 if inline else count |
| 148 | 148 |
| 149 @staticmethod | 149 @staticmethod |
| 150 def __split_transitions(split_count, state): | 150 def __split_transitions(split_count, state): |
| 151 '''Goes through the transitions for 'state' and decides which of them should |
| 152 use the if statement and which should use the switch statement.''' |
| 151 assert not state['switch_transitions'] | 153 assert not state['switch_transitions'] |
| 152 (class_keys, distinct_keys, ranges) = (0, 0, 0) | 154 (class_keys, distinct_keys, ranges) = (0, 0, 0) |
| 153 for (t, r) in state['disjoint_keys']: | 155 for (t, r) in state['disjoint_keys']: |
| 154 if t == 'CLASS': | 156 if t == 'CLASS': |
| 155 class_keys += 1 | 157 class_keys += 1 |
| 156 elif t == 'LATIN_1': | 158 elif t == 'LATIN_1': |
| 157 distinct_keys += r[1] - r[0] + 1 | 159 distinct_keys += r[1] - r[0] + 1 |
| 158 ranges += 1 | 160 ranges += 1 |
| 159 else: | 161 else: |
| 160 raise Exception() | 162 raise Exception() |
| (...skipping 30 matching lines...) Expand all Loading... |
| 191 def f((key, original_node_number)): | 193 def f((key, original_node_number)): |
| 192 return (key, id_map[original_node_number]['node_number']) | 194 return (key, id_map[original_node_number]['node_number']) |
| 193 for state in dfa_states: | 195 for state in dfa_states: |
| 194 state['transitions'] = map(f, state['transitions']) | 196 state['transitions'] = map(f, state['transitions']) |
| 195 assert id_map[self.__start_node_number]['node_number'] == 0 | 197 assert id_map[self.__start_node_number]['node_number'] == 0 |
| 196 assert len(dfa_states) == self.__dfa.node_count() | 198 assert len(dfa_states) == self.__dfa.node_count() |
| 197 # set nodes to inline | 199 # set nodes to inline |
| 198 if self.__inline: | 200 if self.__inline: |
| 199 inlined = reduce(CodeGenerator.__set_inline, dfa_states, 0) | 201 inlined = reduce(CodeGenerator.__set_inline, dfa_states, 0) |
| 200 if self.__log: | 202 if self.__log: |
| 201 print "inlined %s" % inlined | 203 print "%s states inlined" % inlined |
| 202 elif self.__log: | 204 elif self.__log: |
| 203 print "no inlining" | 205 print "no inlining" |
| 204 # split transitions | 206 # split transitions |
| 205 if self.__switching: | 207 if self.__switching: |
| 206 switched = reduce(CodeGenerator.__split_transitions, dfa_states, 0) | 208 switched = reduce(CodeGenerator.__split_transitions, dfa_states, 0) |
| 207 if self.__log: | 209 if self.__log: |
| 208 print "switched states %s" % inlined | 210 print "%s states use switch (instead of if)" % switched |
| 209 elif self.__log: | 211 elif self.__log: |
| 210 print "no switching" | 212 print "no switching" |
| 211 # store states | 213 # store states |
| 212 self.__dfa_states = dfa_states | 214 self.__dfa_states = dfa_states |
| 213 | 215 |
| 214 def process(self): | 216 def process(self): |
| 215 | 217 |
| 216 self.__canonicalize_traversal() | 218 self.__canonicalize_traversal() |
| 217 | 219 |
| 218 dfa_states = self.__dfa_states | 220 dfa_states = self.__dfa_states |
| 219 | 221 |
| 220 default_action = self.__default_action | 222 default_action = self.__default_action |
| 221 assert(default_action and default_action.match_action()) | 223 assert(default_action and default_action.match_action()) |
| 222 default_action = default_action.match_action() | 224 default_action = default_action.match_action() |
| 223 | 225 |
| 224 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | 226 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
| 225 template_env = jinja2.Environment( | 227 template_env = jinja2.Environment( |
| 226 loader = jinja2.PackageLoader('lexer_generator', '.'), | 228 loader = jinja2.PackageLoader('lexer_generator', '.'), |
| 227 undefined = jinja2.StrictUndefined) | 229 undefined = jinja2.StrictUndefined) |
| 228 template = template_env.get_template('code_generator.jinja') | 230 template = template_env.get_template('code_generator.jinja') |
| 229 | 231 |
| 230 return template.render( | 232 return template.render( |
| 231 start_node_number = 0, | 233 start_node_number = 0, |
| 232 debug_print = self.__debug_print, | 234 debug_print = self.__debug_print, |
| 233 default_action = default_action, | 235 default_action = default_action, |
| 234 dfa_states = dfa_states) | 236 dfa_states = dfa_states) |
| OLD | NEW |