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

Unified Diff: tools/lexer_generator/code_generator.py

Issue 160443002: Experimental parser: remove match actions (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/lexer_generator/code_generator.jinja ('k') | tools/lexer_generator/dfa.py » ('j') | 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 85b98c5a56841847dc341fd24b1c12fb6a9dc7ea..a263df63a24fa66e5011cdc90385a14edf385d1b 100644
--- a/tools/lexer_generator/code_generator.py
+++ b/tools/lexer_generator/code_generator.py
@@ -49,7 +49,6 @@ class CodeGenerator:
self.__dfa = dfa
self.__default_action = rule_processor.default_action()
self.__debug_print = debug_print
- self.__start_node_number = self.__dfa.start_state().node_number()
self.__log = log
self.__inline = inline
self.__switching = switching
@@ -60,9 +59,6 @@ class CodeGenerator:
@staticmethod
def __transform_state(encoding, state):
# action data
- action = state.action()
- entry_action = action.entry_action()
- match_action = action.match_action()
# generate ordered transitions
transitions = map(lambda (k, v) : (k, v.node_number()),
state.key_state_iter())
@@ -75,6 +71,7 @@ class CodeGenerator:
transitions = []
(class_keys, distinct_keys, ranges) = (0, 0, 0)
zero_transition = None
+ omega_transition = None
total_transitions = 0
for key, transition_id in old_transitions:
keys = []
@@ -95,16 +92,21 @@ class CodeGenerator:
r = (r[0] + 1, r[1])
keys.append((t, r))
elif t == 'UNIQUE':
- assert r == 'no_match' or r == 'eos'
+ assert r == 'eos'
assert r not in unique_transitions
unique_transitions[r] = transition_id
if r != 'no_match':
total_transitions += 1
+ elif t == 'OMEGA':
+ assert not omega_transition
+ omega_transition = transition_id
+ assert transition_id # TODO(dcarney): fix
+ total_transitions += 1
else:
raise Exception()
if keys:
transitions.append((keys, transition_id))
- # delay zero transition until last
+ # delay zero transition until after all encoded keys
if zero_transition != None:
transitions.append(([('PRIMARY_RANGE', (0, 0))], transition_id))
ranges += 1
@@ -114,7 +116,8 @@ class CodeGenerator:
'original_node_number' : state.node_number(),
'transitions' : transitions,
# flags for code generator
- 'can_elide_read' : total_transitions == 0,
+ 'elide_read' : (total_transitions == 0 or
+ (total_transitions == 1 and omega_transition)),
'is_eos_handler' : False,
'inline' : False,
'must_not_inline' : False,
@@ -123,9 +126,9 @@ class CodeGenerator:
'switch_transitions' : [],
'deferred_transitions' : [],
'unique_transitions' : unique_transitions,
+ 'omega_transition' : omega_transition,
# state actions
- 'entry_action' : entry_action,
- 'match_action' : match_action,
+ 'action' : state.action(),
# statistics for state
'total_transitions' : total_transitions,
'class_keys' : class_keys,
@@ -142,19 +145,28 @@ class CodeGenerator:
self.__jump_table.append((node_id, label))
return len(self.__jump_table) - 1
+ def __terminates_immediately(self, state_id):
+ transition_count = self.__dfa_states[state_id]['total_transitions']
+ if transition_count == 0:
+ return True
+ omega_transition_id = self.__dfa_states[state_id]['omega_transition']
+ if transition_count == 1 and omega_transition_id:
+ return self.__terminates_immediately(omega_transition_id)
+ return False
+
def __set_inline(self, count, state):
inline = False
if state['must_not_inline']:
inline = False
# inline terminal states
- elif not state['total_transitions']:
+ elif self.__terminates_immediately(state['node_number']):
inline = True
# inline next to terminal states with 1 or 2 transitions
elif state['distinct_keys'] < 3 and state['class_keys'] == 0:
inline = True
- # ensure state terminates in 1 step
+ # ensure state terminates in 1 step, excluding omega transitions
for key, state_id in state['transitions']:
- if self.__dfa_states[state_id]['total_transitions']:
+ if not self.__terminates_immediately(state_id):
inline = False
break
state['inline'] = inline
@@ -256,6 +268,9 @@ class CodeGenerator:
CodeGenerator.__reorder(node_number, id_map, dfa_states)
for node_number in current_node['unique_transitions'].values():
CodeGenerator.__reorder(node_number, id_map, dfa_states)
+ if current_node['omega_transition'] != None:
+ CodeGenerator.__reorder(
+ current_node['omega_transition'], id_map, dfa_states)
@staticmethod
def __mark_eos_states(dfa_states, eos_states):
@@ -263,9 +278,9 @@ class CodeGenerator:
state = dfa_states[state_id]
state['is_eos_handler'] = True
state['must_not_inline'] = True
- assert state['match_action']
- assert not state['entry_action']
- assert not state['total_transitions']
+ # TODO(dcarney): bring back
+ # assert state['action']
+ # assert not state['total_transitions']
def __build_dfa_states(self):
dfa_states = []
@@ -275,52 +290,27 @@ class CodeGenerator:
dfa_states = map(f, dfa_states)
id_map = {x['original_node_number'] : x for x in dfa_states}
dfa_states = []
- CodeGenerator.__reorder(self.__start_node_number, id_map, dfa_states)
+ start_node_number = self.__dfa.start_state().node_number()
+ CodeGenerator.__reorder(start_node_number, id_map, dfa_states)
# store states
eos_states = set([])
+ remap = lambda state_id : id_map[state_id]['node_number']
def f((key, original_node_number)):
- return (key, id_map[original_node_number]['node_number'])
+ return (key, remap(original_node_number))
for state in dfa_states:
state['transitions'] = map(f, state['transitions'])
- state['unique_transitions'] = {k : id_map[v]['node_number']
+ state['unique_transitions'] = {k : remap(v)
for k, v in state['unique_transitions'].items()}
+ if state['omega_transition'] != None:
+ state['omega_transition'] = remap(state['omega_transition'])
if 'eos' in state['unique_transitions']:
eos_states.add(state['unique_transitions']['eos'])
- assert id_map[self.__start_node_number]['node_number'] == 0
+ assert id_map[start_node_number]['node_number'] == 0
assert len(dfa_states) == self.__dfa.node_count()
# mark eos states
self.__mark_eos_states(dfa_states, eos_states)
self.__dfa_states = dfa_states
- def __rewrite_gotos(self):
- goto_map = {}
- states = self.__dfa_states
- for state in states:
- if (state['match_action'].name() == 'do_stored_token'):
- assert not state['match_action'].args()[0] in goto_map
- goto_map[state['match_action'].args()[0]] = state['node_number']
- mapped_actions = set([
- 'store_harmony_token_and_goto',
- 'store_token_and_goto',
- 'goto_start'])
- for state in states:
- if not state['match_action']:
- continue
- action = state['match_action'].name()
- if action in mapped_actions:
- value = state['match_action'].args()
- target_id = goto_map[value[-1]]
- states[target_id]['must_not_inline'] = True
- if action != 'goto_start':
- state['can_elide_read'] = False
- label = 'after_entry_code'
- else:
- states[target_id]['can_elide_read'] = False
- label = 'state_entry'
- jump_label = self.__register_jump(target_id, label)
- new_args = list(value[:-1]) + [str(jump_label)]
- state['match_action'] = Term(action, *new_args)
-
def __inlined_state(self, target_id):
state = deepcopy(self.__dfa_states[target_id])
state['node_number'] = len(self.__dfa_states)
@@ -364,6 +354,9 @@ class CodeGenerator:
return (key, self.__register_jump(target_id, jump_type))
for name in transition_names:
state[name] = map(generate_jump, state[name])
+ if state['omega_transition'] != None:
+ state['omega_transition'] = generate_jump(
+ (None, state['omega_transition']))[1]
if 'eos' in state['unique_transitions']:
eos_state_id = state['unique_transitions']['eos']
# eos state is not inlined, don't need to look in map
@@ -392,8 +385,6 @@ class CodeGenerator:
# rewrite deferred transitions
for state in dfa_states:
self.__rewrite_deferred_transitions(state)
- # rewrite gotos
- self.__rewrite_gotos()
# set nodes to inline
if self.__inline:
inlined = reduce(self.__set_inline, dfa_states, 0)
@@ -407,8 +398,7 @@ class CodeGenerator:
self.__dfa_states[0]['entry_points']['state_entry'] = True
default_action = self.__default_action
- assert(default_action and default_action.match_action())
- default_action = default_action.match_action()
+ assert default_action
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
template_env = jinja2.Environment(
« no previous file with comments | « tools/lexer_generator/code_generator.jinja ('k') | tools/lexer_generator/dfa.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698