Revision: 17850
Author: [email protected]
Date: Mon Nov 18 20:02:55 2013 UTC
Log: Experimental parser: switch blocks
[email protected]
BUG=
Review URL: https://codereview.chromium.org/73453006
http://code.google.com/p/v8/source/detail?r=17850
Modified:
/branches/experimental/parser/tools/lexer_generator/code_generator.jinja
/branches/experimental/parser/tools/lexer_generator/code_generator.py
=======================================
---
/branches/experimental/parser/tools/lexer_generator/code_generator.jinja
Mon Nov 18 18:42:04 2013 UTC
+++
/branches/experimental/parser/tools/lexer_generator/code_generator.jinja
Mon Nov 18 20:02:55 2013 UTC
@@ -3,7 +3,7 @@
{# TODO implement CLASS checks #}
{%- macro do_key(key) -%}
- {%- for r in key.range_iter() -%}
+ {%- for r in key -%}
{%- if not loop.first %} || {% endif -%}
{%- if r[0] == 'LATIN_1' -%}
{%- if r[1][0] == r[1][1] -%}
@@ -82,11 +82,26 @@
{%- if debug_print %}
fprintf(stderr, "char at hand is %c (%d)\n", yych, yych);
{% endif -%}
+
+ {%- if state['switch_transitions'] -%}
+ switch(yych) {
+ {%- for key, transition_state_id in state['switch_transitions'] %}
+ case {{key}}:
+ {%- set inline_transition =
dfa_states[transition_state_id]['inline'] %}
+ FORWARD();
+ {%- if inline_transition %}
+ {{ do_dfa_state(transition_state_id, True) }}
+ {% else %}
+ goto code_{{transition_state_id}};
+ {% endif %}
+ {% endfor -%}
+ }
+ {%- endif -%}
{%- for key, transition_state_id in state.transitions %}
- {%- set inline_transition = dfa_states[transition_state_id]['inline']
-%}
if ({{do_key(key)}}) {
- FORWARD();
+ {%- set inline_transition =
dfa_states[transition_state_id]['inline'] %}
+ FORWARD();
{%- if inline_transition %}
{{ do_dfa_state(transition_state_id, True) }}
{% else %}
=======================================
--- /branches/experimental/parser/tools/lexer_generator/code_generator.py
Mon Nov 18 18:42:04 2013 UTC
+++ /branches/experimental/parser/tools/lexer_generator/code_generator.py
Mon Nov 18 20:02:55 2013 UTC
@@ -37,6 +37,7 @@
rule_processor,
minimize_default = True,
inline = True,
+ switching = True,
debug_print = False,
log = False):
if minimize_default:
@@ -49,6 +50,7 @@
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 @@
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 @@
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 @@
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):
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.