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

Unified Diff: tools/lexer_generator/backtracking_generator.py

Issue 172893003: Experimental parser: add dfa path iterator (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 | « src/lexer/lexer_py.re ('k') | tools/lexer_generator/code_generator.jinja » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/lexer_generator/backtracking_generator.py
diff --git a/tools/lexer_generator/backtracking_generator.py b/tools/lexer_generator/backtracking_generator.py
index 9bb6db6b31fc72813c5a918f3ebaed242fba0bca..475647525b4c5c18a0fb9e653248c431f793bd7e 100644
--- a/tools/lexer_generator/backtracking_generator.py
+++ b/tools/lexer_generator/backtracking_generator.py
@@ -40,6 +40,36 @@ class BacktrackingGenerator(object):
self.__default_action = default_action
self.__log = log
+ @staticmethod
+ def __process_error_states(dfa, error_map, action_state_map):
+ path_map = { k : [] for k in error_map.iterkeys()}
+ error_states = set(error_map.iterkeys())
+ for path, states_in_path, terminal in dfa.path_iter():
+ matching = error_states & states_in_path
+ if not matching:
+ continue
+ last_action = None
+ path_length = 0
+ for (key, state) in path:
+ if state in error_states:
+ assert last_action != None
+ path_map[state].append([k for k, s in path[1:path_length]])
+ elif state in action_state_map:
+ last_action = state
+ path_length += 1
+ print reduce(lambda acc, x : acc + len(x), path_map.itervalues(), 0)
+ for state, key_paths in path_map.iteritems():
+ count = 0
+ action_str = map(str, error_map[state][0])
+ for key_path in key_paths:
+ print "path %d %s %s" % (
+ state.node_number(),
+ action_str,
+ " --> ".join(map(str, key_path)))
+ count += 1
+ if count > 10:
+ break
+
def __generate(self):
dfa = self.__dfa
default_action = self.__default_action
@@ -72,6 +102,7 @@ class BacktrackingGenerator(object):
if (not start_state in incoming_transitions and
not start_state in action_states):
action_states[start_state] = default_action
+ error_map = {}
for state in incoming_transitions.iterkeys():
if state in omega_states or state in action_states:
continue
@@ -98,12 +129,11 @@ class BacktrackingGenerator(object):
next.add(incoming_state)
seen |= unchecked
unchecked = next - seen
- # accumulate unique actions
+ # Accumulate unique actions.
actions = set(map(lambda x : action_states[x].term(), match_edge))
assert actions
if not len(actions) == 1:
- # TODO(dcarney): need to warn here after second pass
- # actions = set([default_action])
+ error_map[state] = actions, match_edge
continue
action = iter(actions).next()
# don't install default actions
@@ -111,6 +141,11 @@ class BacktrackingGenerator(object):
continue
store_states |= match_edge
backtracking_map[state.node_number()] = (action, match_edge)
+ # Bail if error occurred.
+ if error_map:
+ self.__process_error_states(dfa, error_map, action_states)
+ raise Exception('ambiguous backtracking')
+ # Now install backtracking everywhere.
def install_backtracking_action(new_states, node_number):
omega_state_id = str(node_number) + '_bt'
key = TransitionKey.omega()
« no previous file with comments | « src/lexer/lexer_py.re ('k') | tools/lexer_generator/code_generator.jinja » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698