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

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

Issue 75513002: Experimental parser: inline rules (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
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 15 matching lines...) Expand all
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 import os 28 import os
29 import sys 29 import sys
30 import jinja2 30 import jinja2
31 from dfa import Dfa 31 from dfa import Dfa
32 from transition_keys import TransitionKey 32 from transition_keys import TransitionKey
33 33
34 class CodeGenerator: 34 class CodeGenerator:
35 35
36 def __init__(self, rule_processor, use_mdfa, debug_print = False): 36 def __init__(self,
37 if use_mdfa: 37 rule_processor,
38 minimize_default = True,
39 inline = True,
40 debug_print = False,
41 log = False):
42 if minimize_default:
38 dfa = rule_processor.default_automata().minimal_dfa() 43 dfa = rule_processor.default_automata().minimal_dfa()
39 else: 44 else:
40 dfa = rule_processor.default_automata().dfa() 45 dfa = rule_processor.default_automata().dfa()
41 self.__dfa = dfa 46 self.__dfa = dfa
42 self.__default_action = rule_processor.default_action 47 self.__default_action = rule_processor.default_action
43 self.__debug_print = debug_print 48 self.__debug_print = debug_print
44 self.__start_node_number = self.__dfa.start_state().node_number() 49 self.__start_node_number = self.__dfa.start_state().node_number()
50 self.__log = log
51 self.__inline = inline
45 52
46 def __state_cmp(self, left, right): 53 def __state_cmp(self, left, right):
47 if left['original_node_number'] == self.__start_node_number: 54 if left['original_node_number'] == self.__start_node_number:
48 return -1 55 return -1
49 if right['original_node_number'] == self.__start_node_number: 56 if right['original_node_number'] == self.__start_node_number:
50 return 1 57 return 1
51 c = cmp(len(left['disjoint_keys']), len(right['disjoint_keys'])) 58 c = cmp(len(left['disjoint_keys']), len(right['disjoint_keys']))
52 if c: 59 if c:
53 return c 60 return c
54 c = cmp(left['disjoint_keys'], right['disjoint_keys']) 61 c = cmp(left['disjoint_keys'], right['disjoint_keys'])
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 state.transitions().items()) 109 state.transitions().items())
103 def cmp(left, right): 110 def cmp(left, right):
104 return TransitionKey.canonical_compare(left[0], right[0]) 111 return TransitionKey.canonical_compare(left[0], right[0])
105 transitions = sorted(transitions, cmp) 112 transitions = sorted(transitions, cmp)
106 # dictionary object representing state 113 # dictionary object representing state
107 return { 114 return {
108 'node_number' : state.node_number(), 115 'node_number' : state.node_number(),
109 'original_node_number' : state.node_number(), 116 'original_node_number' : state.node_number(),
110 'transitions' : transitions, 117 'transitions' : transitions,
111 'disjoint_keys' : keys, 118 'disjoint_keys' : keys,
112 'inline' : False, 119 'inline' : None,
113 'depth' : None, 120 'depth' : None,
114 'action' : action, 121 'action' : action,
115 'entry_action' : entry_action, 122 'entry_action' : entry_action,
116 'match_action' : match_action, 123 'match_action' : match_action,
117 } 124 }
118 125
119 @staticmethod 126 @staticmethod
120 def __compute_depths(node_number, depth, id_map): 127 def __compute_depths(node_number, depth, id_map):
121 state = id_map[node_number] 128 state = id_map[node_number]
122 if state['depth'] != None: 129 if state['depth'] != None:
123 return 130 return
124 state['depth'] = depth 131 state['depth'] = depth
125 for (k, transition_node) in state['transitions']: 132 for (k, transition_node) in state['transitions']:
126 CodeGenerator.__compute_depths(transition_node, depth + 1, id_map) 133 CodeGenerator.__compute_depths(transition_node, depth + 1, id_map)
127 134
135 @staticmethod
136 def __set_inline(count, state):
137 assert state['inline'] == None
138 inline = False
139 if not state['transitions']:
140 inline = True
141 state['inline'] = inline
142 return count + 1 if inline else count
143
128 def __canonicalize_traversal(self): 144 def __canonicalize_traversal(self):
129 dfa_states = [] 145 dfa_states = []
130 self.__dfa.visit_all_states(lambda state, acc: dfa_states.append(state)) 146 self.__dfa.visit_all_states(lambda state, acc: dfa_states.append(state))
131 dfa_states = map(CodeGenerator.__transform_state, dfa_states) 147 dfa_states = map(CodeGenerator.__transform_state, dfa_states)
132 id_map = {x['original_node_number'] : x for x in dfa_states} 148 id_map = {x['original_node_number'] : x for x in dfa_states}
133 CodeGenerator.__compute_depths(self.__start_node_number, 1, id_map) 149 CodeGenerator.__compute_depths(self.__start_node_number, 1, id_map)
134 dfa_states = sorted(dfa_states, cmp=self.__state_cmp) 150 dfa_states = sorted(dfa_states, cmp=self.__state_cmp)
135 # remap all node numbers 151 # remap all node numbers
136 for i, state in enumerate(dfa_states): 152 for i, state in enumerate(dfa_states):
137 state['node_number'] = i 153 state['node_number'] = i
138 def f((key, original_node_number)): 154 def f((key, original_node_number)):
139 return (key, id_map[original_node_number]['node_number']) 155 return (key, id_map[original_node_number]['node_number'])
140 for state in dfa_states: 156 for state in dfa_states:
141 state['transitions'] = map(f, state['transitions']) 157 state['transitions'] = map(f, state['transitions'])
142 assert id_map[self.__start_node_number]['node_number'] == 0 158 assert id_map[self.__start_node_number]['node_number'] == 0
159 assert len(dfa_states) == self.__dfa.node_count()
160 # set nodes to inline
161 if self.__inline:
162 inlined = reduce(CodeGenerator.__set_inline, dfa_states, 0)
163 if self.__log:
164 print "inlined %s" % inlined
165 elif self.__log:
166 print "no inlining"
143 self.__dfa_states = dfa_states 167 self.__dfa_states = dfa_states
144 168
145 def process(self): 169 def process(self):
146 170
147 self.__canonicalize_traversal() 171 self.__canonicalize_traversal()
148 172
149 start_node_number = self.__start_node_number
150 dfa_states = self.__dfa_states 173 dfa_states = self.__dfa_states
151 assert len(dfa_states) == self.__dfa.node_count()
152 assert dfa_states[0]['node_number'] == 0
153 174
154 default_action = self.__default_action 175 default_action = self.__default_action
155 assert(default_action and default_action.match_action()) 176 assert(default_action and default_action.match_action())
156 default_action = default_action.match_action() 177 default_action = default_action.match_action()
157 178
158 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 179 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
159 template_env = jinja2.Environment( 180 template_env = jinja2.Environment(
160 loader = jinja2.PackageLoader('lexer_generator', '.'), 181 loader = jinja2.PackageLoader('lexer_generator', '.'),
161 undefined = jinja2.StrictUndefined) 182 undefined = jinja2.StrictUndefined)
162 template = template_env.get_template('code_generator.jinja') 183 template = template_env.get_template('code_generator.jinja')
163 184
164 return template.render( 185 return template.render(
165 start_node_number = 0, 186 start_node_number = 0,
166 debug_print = self.__debug_print, 187 debug_print = self.__debug_print,
167 default_action = default_action, 188 default_action = default_action,
168 dfa_states = dfa_states) 189 dfa_states = dfa_states)
OLDNEW
« no previous file with comments | « tools/lexer_generator/code_generator.jinja ('k') | tools/lexer_generator/code_generator_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698