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

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

Issue 82983002: Experimental parser: KeyEncoding class added (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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/automaton.py ('k') | tools/lexer_generator/code_generator_test.py » ('j') | 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 17 matching lines...) Expand all
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, 36 def __init__(self,
37 rule_processor, 37 rule_processor,
38 encoding = 'latin1',
39 minimize_default = True, 38 minimize_default = True,
40 inline = True, 39 inline = True,
41 switching = True, 40 switching = True,
42 debug_print = False, 41 debug_print = False,
43 log = False): 42 log = False):
44 if minimize_default: 43 if minimize_default:
45 dfa = rule_processor.default_automata().minimal_dfa() 44 dfa = rule_processor.default_automata().minimal_dfa()
46 else: 45 else:
47 dfa = rule_processor.default_automata().dfa() 46 dfa = rule_processor.default_automata().dfa()
48 self.__dfa = dfa 47 self.__dfa = dfa
49 self.__default_action = rule_processor.default_action 48 self.__default_action = rule_processor.default_action
50 self.__debug_print = debug_print 49 self.__debug_print = debug_print
51 self.__start_node_number = self.__dfa.start_state().node_number() 50 self.__start_node_number = self.__dfa.start_state().node_number()
52 self.__log = log 51 self.__log = log
53 self.__inline = inline 52 self.__inline = inline
54 self.__switching = switching 53 self.__switching = switching
55 self.__encoding = encoding
56 54
57 def __state_cmp(self, left, right): 55 def __state_cmp(self, left, right):
58 if left['original_node_number'] == self.__start_node_number: 56 if left['original_node_number'] == self.__start_node_number:
59 return -1 57 return -1
60 if right['original_node_number'] == self.__start_node_number: 58 if right['original_node_number'] == self.__start_node_number:
61 return 1 59 return 1
62 c = cmp(len(left['disjoint_keys']), len(right['disjoint_keys'])) 60 c = cmp(len(left['disjoint_keys']), len(right['disjoint_keys']))
63 if c: 61 if c:
64 return c 62 return c
65 c = cmp(left['disjoint_keys'], right['disjoint_keys']) 63 c = cmp(left['disjoint_keys'], right['disjoint_keys'])
(...skipping 23 matching lines...) Expand all
89 return cmp(left[1], right[1]) 87 return cmp(left[1], right[1])
90 assert right[0] == 'CLASS' 88 assert right[0] == 'CLASS'
91 return -1 89 return -1
92 assert left[0] == 'CLASS' 90 assert left[0] == 'CLASS'
93 if right[0] == 'LATIN_1': 91 if right[0] == 'LATIN_1':
94 return 1 92 return 1
95 # TODO store numeric values and cmp 93 # TODO store numeric values and cmp
96 return cmp(left[1], right[1]) 94 return cmp(left[1], right[1])
97 95
98 @staticmethod 96 @staticmethod
99 def __transform_state(state): 97 def __transform_state(encoding, state):
100 # action data 98 # action data
101 action = state.action() 99 action = state.action()
102 entry_action = None if not action else action.entry_action() 100 entry_action = None if not action else action.entry_action()
103 match_action = None if not action else action.match_action() 101 match_action = None if not action else action.match_action()
104 # generate ordered transitions 102 # generate ordered transitions
105 transitions = map(lambda (k, v) : (k, v.node_number()), 103 transitions = map(lambda (k, v) : (k, v.node_number()),
106 state.transitions().items()) 104 state.transitions().items())
107 def cmp(left, right): 105 def cmp(left, right):
108 return TransitionKey.canonical_compare(left[0], right[0]) 106 return TransitionKey.canonical_compare(left[0], right[0])
109 transitions = sorted(transitions, cmp) 107 transitions = sorted(transitions, cmp)
110 # map transition keys to disjoint ranges 108 # map transition keys to disjoint ranges
111 disjoint_keys = {'value' : []} 109 disjoint_keys = {'value' : []}
112 def f((key, state)): 110 def f((key, state)):
113 ranges = list(key.range_iter()) 111 ranges = list(key.range_iter(encoding))
114 disjoint_keys['value'] += ranges 112 disjoint_keys['value'] += ranges
115 return (ranges, state) 113 return (ranges, state)
116 transitions = map(f, transitions) 114 transitions = map(f, transitions)
117 disjoint_keys = sorted(disjoint_keys['value'], CodeGenerator.__range_cmp) 115 disjoint_keys = sorted(disjoint_keys['value'], CodeGenerator.__range_cmp)
118 # dictionary object representing state 116 # dictionary object representing state
119 (class_keys, distinct_keys, ranges) = (0, 0, 0) 117 (class_keys, distinct_keys, ranges) = (0, 0, 0)
120 for (t, r) in disjoint_keys: 118 for (t, r) in disjoint_keys:
121 if t == 'CLASS': 119 if t == 'CLASS':
122 class_keys += 1 120 class_keys += 1
123 elif t == 'LATIN_1': 121 elif t == 'LATIN_1':
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 if d: 194 if d:
197 deferred_transitions.append((d, node_id)) 195 deferred_transitions.append((d, node_id))
198 state['transitions'] = if_transitions 196 state['transitions'] = if_transitions
199 state['switch_transitions'] = switch_transitions 197 state['switch_transitions'] = switch_transitions
200 state['deferred_transitions'] = deferred_transitions 198 state['deferred_transitions'] = deferred_transitions
201 return split_count + (0 if no_switch else 1) 199 return split_count + (0 if no_switch else 1)
202 200
203 def __canonicalize_traversal(self): 201 def __canonicalize_traversal(self):
204 dfa_states = [] 202 dfa_states = []
205 self.__dfa.visit_all_states(lambda state, acc: dfa_states.append(state)) 203 self.__dfa.visit_all_states(lambda state, acc: dfa_states.append(state))
206 dfa_states = map(CodeGenerator.__transform_state, dfa_states) 204 encoding = self.__dfa.encoding()
205 f = lambda state : CodeGenerator.__transform_state(encoding, state)
206 dfa_states = map(f, dfa_states)
207 id_map = {x['original_node_number'] : x for x in dfa_states} 207 id_map = {x['original_node_number'] : x for x in dfa_states}
208 CodeGenerator.__compute_depths(self.__start_node_number, 1, id_map) 208 CodeGenerator.__compute_depths(self.__start_node_number, 1, id_map)
209 dfa_states = sorted(dfa_states, cmp=self.__state_cmp) 209 dfa_states = sorted(dfa_states, cmp=self.__state_cmp)
210 # remap all node numbers 210 # remap all node numbers
211 for i, state in enumerate(dfa_states): 211 for i, state in enumerate(dfa_states):
212 state['node_number'] = i 212 state['node_number'] = i
213 def f((key, original_node_number)): 213 def f((key, original_node_number)):
214 return (key, id_map[original_node_number]['node_number']) 214 return (key, id_map[original_node_number]['node_number'])
215 for state in dfa_states: 215 for state in dfa_states:
216 state['transitions'] = map(f, state['transitions']) 216 state['transitions'] = map(f, state['transitions'])
(...skipping 22 matching lines...) Expand all
239 default_action = self.__default_action 239 default_action = self.__default_action
240 assert(default_action and default_action.match_action()) 240 assert(default_action and default_action.match_action())
241 default_action = default_action.match_action() 241 default_action = default_action.match_action()
242 242
243 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 243 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
244 template_env = jinja2.Environment( 244 template_env = jinja2.Environment(
245 loader = jinja2.PackageLoader('lexer_generator', '.'), 245 loader = jinja2.PackageLoader('lexer_generator', '.'),
246 undefined = jinja2.StrictUndefined) 246 undefined = jinja2.StrictUndefined)
247 template = template_env.get_template('code_generator.jinja') 247 template = template_env.get_template('code_generator.jinja')
248 248
249 if self.__encoding == 'latin1': 249 encoding = self.__dfa.encoding().name()
250 if encoding == 'latin1':
250 char_type = 'uint8_t' 251 char_type = 'uint8_t'
251 elif self.__encoding == 'utf16': 252 elif encoding == 'utf16':
252 char_type = 'uint16_t' 253 char_type = 'uint16_t'
253 else: 254 else:
254 raise Exception('Unsupported encoding %s' % encoding) 255 raise Exception('Unsupported encoding %s' % encoding)
255 return template.render( 256 return template.render(
256 start_node_number = 0, 257 start_node_number = 0,
257 debug_print = self.__debug_print, 258 debug_print = self.__debug_print,
258 default_action = default_action, 259 default_action = default_action,
259 dfa_states = dfa_states, 260 dfa_states = dfa_states,
260 encoding = self.__encoding, 261 encoding = encoding,
261 char_type = char_type) 262 char_type = char_type)
OLDNEW
« no previous file with comments | « tools/lexer_generator/automaton.py ('k') | tools/lexer_generator/code_generator_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698