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

Unified Diff: tools/lexer_generator/code_generator.py

Issue 73453006: Experimental parser: switch blocks (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/lexer_generator/code_generator.jinja ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/lexer_generator/code_generator.py
diff --git a/tools/lexer_generator/code_generator.py b/tools/lexer_generator/code_generator.py
index 1234c4f6f4d6b0d5acc594436064124acae3d659..42a990e60e9d09df02b667fbcc40d2b66c47806d 100644
--- a/tools/lexer_generator/code_generator.py
+++ b/tools/lexer_generator/code_generator.py
@@ -37,6 +37,7 @@ class CodeGenerator:
rule_processor,
minimize_default = True,
inline = True,
+ switching = True,
debug_print = False,
log = False):
if minimize_default:
@@ -49,6 +50,7 @@ class CodeGenerator:
self.__start_node_number = self.__dfa.start_state().node_number()
self.__log = log
self.__inline = inline
+ self.__switching = switching
def __state_cmp(self, left, right):
if left['original_node_number'] == self.__start_node_number:
@@ -97,25 +99,27 @@ class CodeGenerator:
action = state.action()
entry_action = None if not action else action.entry_action()
match_action = None if not action else action.match_action()
- # compute disjoint ranges
- keys = TransitionKey.disjoint_keys(list(state.key_iter()))
- def f(key):
- ranges = list(key.range_iter())
- assert len(ranges) == 1
- return ranges[0]
- keys = sorted(map(f, keys), CodeGenerator.__range_cmp)
# generate ordered transitions
transitions = map(lambda (k, v) : (k, v.node_number()),
state.transitions().items())
def cmp(left, right):
return TransitionKey.canonical_compare(left[0], right[0])
transitions = sorted(transitions, cmp)
+ # map transition keys to disjoint ranges
+ disjoint_keys = {'value' : []}
+ def f((key, state)):
+ ranges = list(key.range_iter())
+ disjoint_keys['value'] += ranges
+ return (ranges, state)
+ transitions = map(f, transitions)
+ disjoint_keys = sorted(disjoint_keys['value'], CodeGenerator.__range_cmp)
# dictionary object representing state
return {
'node_number' : state.node_number(),
'original_node_number' : state.node_number(),
'transitions' : transitions,
- 'disjoint_keys' : keys,
+ 'switch_transitions' : [],
+ 'disjoint_keys' : disjoint_keys,
'inline' : None,
'depth' : None,
'action' : action,
@@ -138,9 +142,40 @@ class CodeGenerator:
inline = False
if not state['transitions']:
inline = True
+ # TODO add in 1 or 2 element if blocks
state['inline'] = inline
return count + 1 if inline else count
+ @staticmethod
+ def __split_transitions(split_count, state):
+ assert not state['switch_transitions']
+ (class_keys, distinct_keys, ranges) = (0, 0, 0)
+ for (t, r) in state['disjoint_keys']:
+ if t == 'CLASS':
+ class_keys += 1
+ elif t == 'LATIN_1':
+ distinct_keys += r[1] - r[0] + 1
+ ranges += 1
+ else:
+ raise Exception()
+ if distinct_keys <= 7 or float(distinct_keys)/float(ranges) >= 7.0:
+ return split_count
+ switch_transitions = []
+ if_transitions = []
+ for (ranges, node_id) in state['transitions']:
+ i = []
+ for r in ranges:
+ if r[0] == 'CLASS':
+ i.append(r)
+ else:
+ for x in range(r[1][0], r[1][1] + 1):
+ switch_transitions.append((x, node_id))
+ if i:
+ if_transitions.append((i, node_id))
+ state['transitions'] = if_transitions
+ state['switch_transitions'] = switch_transitions
+ return split_count + 1
+
def __canonicalize_traversal(self):
dfa_states = []
self.__dfa.visit_all_states(lambda state, acc: dfa_states.append(state))
@@ -164,6 +199,14 @@ class CodeGenerator:
print "inlined %s" % inlined
elif self.__log:
print "no inlining"
+ # split transitions
+ if self.__switching:
+ switched = reduce(CodeGenerator.__split_transitions, dfa_states, 0)
+ if self.__log:
+ print "switched states %s" % inlined
+ elif self.__log:
+ print "no switching"
+ # store states
self.__dfa_states = dfa_states
def process(self):
« 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