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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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]) |
OLD | NEW |