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

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

Issue 144003014: Experimental parser: cleanup state transformation in code generator (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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 dfa = rule_processor.default_automata().dfa() 46 dfa = rule_processor.default_automata().dfa()
47 self.__dfa = dfa 47 self.__dfa = dfa
48 self.__default_action = rule_processor.default_action 48 self.__default_action = rule_processor.default_action
49 self.__debug_print = debug_print 49 self.__debug_print = debug_print
50 self.__start_node_number = self.__dfa.start_state().node_number() 50 self.__start_node_number = self.__dfa.start_state().node_number()
51 self.__log = log 51 self.__log = log
52 self.__inline = inline 52 self.__inline = inline
53 self.__switching = switching 53 self.__switching = switching
54 54
55 @staticmethod 55 @staticmethod
56 def __range_cmp(left, right):
57 if left[0] == 'PRIMARY_RANGE':
58 if right[0] == 'PRIMARY_RANGE':
59 return cmp(left[1], right[1])
60 assert right[0] == 'CLASS'
61 return -1
62 assert left[0] == 'CLASS'
63 if right[0] == 'PRIMARY_RANGE':
64 return 1
65 # TODO store numeric values and cmp
66 return cmp(left[1], right[1])
67
68 @staticmethod
69 def __transform_state(encoding, state): 56 def __transform_state(encoding, state):
70 # action data 57 # action data
71 action = state.action() 58 action = state.action()
72 entry_action = None if not action else action.entry_action() 59 entry_action = None if not action else action.entry_action()
73 match_action = None if not action else action.match_action() 60 match_action = None if not action else action.match_action()
74 # generate ordered transitions 61 # generate ordered transitions
75 transitions = map(lambda (k, v) : (k, v.node_number()), 62 transitions = map(lambda (k, v) : (k, v.node_number()),
76 state.transitions().items()) 63 state.transitions().items())
77 def cmp(left, right): 64 def cmp(left, right):
78 return TransitionKey.canonical_compare(left[0], right[0]) 65 return TransitionKey.canonical_compare(left[0], right[0])
79 transitions = sorted(transitions, cmp) 66 transitions = sorted(transitions, cmp)
80 # map transition keys to disjoint ranges 67 # map transition keys to disjoint ranges and collect stats
81 disjoint_keys = {'value' : []} 68 disjoint_keys = []
82 def f((key, state)): 69 eos_transition = None
83 ranges = list(key.range_iter(encoding)) 70 old_transitions = transitions
84 disjoint_keys['value'] += ranges 71 transitions = []
85 return (ranges, state)
86 transitions = map(f, transitions)
87 disjoint_keys = sorted(disjoint_keys['value'], CodeGenerator.__range_cmp)
88 # dictionary object representing state
89 (class_keys, distinct_keys, ranges) = (0, 0, 0) 72 (class_keys, distinct_keys, ranges) = (0, 0, 0)
90 for (t, r) in disjoint_keys: 73 for key, transition_id in old_transitions:
91 if t == 'CLASS': 74 keys = list(key.range_iter(encoding))
92 class_keys += 1 75 eos_found = False
93 elif t == 'PRIMARY_RANGE': 76 for (t, r) in keys:
94 distinct_keys += r[1] - r[0] + 1 77 if t == 'CLASS':
95 ranges += 1 78 class_keys += 1
96 else: 79 elif t == 'PRIMARY_RANGE':
97 raise Exception() 80 distinct_keys += r[1] - r[0] + 1
81 ranges += 1
82 elif t == 'UNIQUE':
83 assert r == 'eos'
84 assert len(keys) == 1
85 assert eos_transition == None
86 eos_transition = transition_id
87 eos_found = True
88 else:
89 raise Exception()
90 if not eos_found:
91 transitions.append((keys, transition_id))
92 # eos_transitions is for a followup cl
93 assert not eos_transition
98 return { 94 return {
99 'node_number' : None, 95 'node_number' : None,
100 'original_node_number' : state.node_number(), 96 'original_node_number' : state.node_number(),
101 'transitions' : transitions, 97 'transitions' : transitions,
98 # flags for code generator
102 'can_elide_read' : len(transitions) == 0, 99 'can_elide_read' : len(transitions) == 0,
100 'is_eos_handler' : False,
101 'inline' : None,
102 # transitions for code generator
103 'if_transitions' : [],
103 'switch_transitions' : [], 104 'switch_transitions' : [],
104 'deferred_transitions' : [], 105 'deferred_transitions' : [],
105 'long_char_transitions' : [], 106 'long_char_transitions' : [],
106 'disjoint_keys' : disjoint_keys, 107 'eos_transition' : eos_transition,
107 'inline' : None, 108 # state actions
108 'action' : action,
109 'entry_action' : entry_action, 109 'entry_action' : entry_action,
110 'match_action' : match_action, 110 'match_action' : match_action,
111 # statistics for states
111 'class_keys' : class_keys, 112 'class_keys' : class_keys,
112 'distinct_keys' : distinct_keys, 113 'distinct_keys' : distinct_keys,
113 'ranges' : ranges, 114 'ranges' : ranges,
114 # record of which entry points will be needed 115 # record of which entry points will be needed
115 'entry_points' : { 116 'entry_points' : {
116 'state_entry' : True, 117 'state_entry' : True,
117 'after_entry_code' : False, 118 'after_entry_code' : False,
118 # 'before_match' : False, 119 # 'before_match' : False,
119 # 'before_deferred' : False, 120 # 'before_deferred' : False,
120 } 121 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 elif no_switch: 158 elif no_switch:
158 i.append(r) 159 i.append(r)
159 else: 160 else:
160 s.append(r[1]) 161 s.append(r[1])
161 if i: 162 if i:
162 if_transitions.append((i, node_id)) 163 if_transitions.append((i, node_id))
163 if s: 164 if s:
164 switch_transitions.append((s, node_id)) 165 switch_transitions.append((s, node_id))
165 if d: 166 if d:
166 deferred_transitions.append((d, node_id)) 167 deferred_transitions.append((d, node_id))
167 state['transitions'] = if_transitions 168 state['if_transitions'] = if_transitions
168 state['switch_transitions'] = switch_transitions 169 state['switch_transitions'] = switch_transitions
169 state['deferred_transitions'] = deferred_transitions 170 state['deferred_transitions'] = deferred_transitions
170 return split_count + (0 if no_switch else 1) 171 return split_count + (0 if no_switch else 1)
171 172
172 __call_map = { 173 __call_map = {
173 'non_primary_whitespace' : 'IsWhiteSpaceNotLineTerminator', 174 'non_primary_whitespace' : 'IsWhiteSpaceNotLineTerminator',
174 'non_primary_letter' : 'IsLetter', 175 'non_primary_letter' : 'IsLetter',
175 'non_primary_identifier_part_not_letter' : 'IsIdentifierPartNotLetter', 176 'non_primary_identifier_part_not_letter' : 'IsIdentifierPartNotLetter',
176 'non_primary_line_terminator' : 'IsLineTerminator', 177 'non_primary_line_terminator' : 'IsLineTerminator',
177 } 178 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 char_type = char_types[encoding.name()] 339 char_type = char_types[encoding.name()]
339 340
340 return template.render( 341 return template.render(
341 start_node_number = 0, 342 start_node_number = 0,
342 debug_print = self.__debug_print, 343 debug_print = self.__debug_print,
343 default_action = default_action, 344 default_action = default_action,
344 dfa_states = dfa_states, 345 dfa_states = dfa_states,
345 encoding = encoding.name(), 346 encoding = encoding.name(),
346 char_type = char_type, 347 char_type = char_type,
347 upper_bound = encoding.primary_range()[1]) 348 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