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

Unified Diff: tools/lexer_generator/nfa.py

Issue 69293005: Experimental parser: add catch all rule (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
Index: tools/lexer_generator/nfa.py
diff --git a/tools/lexer_generator/nfa.py b/tools/lexer_generator/nfa.py
index 30fade56de7c400184e8621bd34d53264e9cdffa..cbc9a9f301334fa0803708be70a5acd1fb98bed9 100644
--- a/tools/lexer_generator/nfa.py
+++ b/tools/lexer_generator/nfa.py
@@ -106,10 +106,27 @@ class NfaState(AutomatonState):
def key_matches(self, value):
return self.__matches(lambda k, v : k.matches_key(v), value)
+ def replace_catch_all(self):
+ catch_all = TransitionKey.unique('catch_all')
+ if not catch_all in self.__transitions:
+ return
+ f = lambda acc, state: acc | state.__epsilon_closure
+ reachable_states = reduce(f, self.__transitions[catch_all], set())
+ f = lambda acc, state: acc | set(state.__transitions.keys())
+ keys = reduce(f, reachable_states, set())
+ keys.discard(TransitionKey.epsilon())
+ keys.discard(catch_all)
+ inverse_key = TransitionKey.inverse_key(keys)
+ if inverse_key:
+ self.__transitions[inverse_key] = self.__transitions[catch_all]
+ del self.__transitions[catch_all]
+
@staticmethod
def gather_transition_keys(state_set):
f = lambda acc, state: acc | set(state.__transitions.keys())
- return TransitionKey.disjoint_keys(reduce(f, state_set, set()))
+ keys = reduce(f, state_set, set())
+ keys.discard(TransitionKey.epsilon())
+ return TransitionKey.disjoint_keys(keys)
class NfaBuilder:
@@ -202,6 +219,12 @@ class NfaBuilder:
def __any(self, graph):
return self.__key_state(TransitionKey.any())
+ def __epsilon(self, graph):
+ start = self.__new_state()
+ end = self.__new_state()
+ start.close(end)
+ return (start, [end])
+
def __action(self, graph):
(start, ends) = self.__process(graph[1])
action = graph[2]
@@ -215,19 +238,11 @@ class NfaBuilder:
state = self.__peek_state()
if not state['start_node']:
state['start_node'] = self.__new_state()
- end = self.__new_state()
- self.__patch_ends(ends, end)
- ends = [end]
- end.add_epsilon_transition(state['start_node'])
- return (start, ends)
+ self.__patch_ends(ends, state['start_node'])
+ return (start, [])
- def __break(self, graph):
- (start, ends) = self.__process(graph[1])
- self.__peek_state()['unpatched_ends'] += ends
- new_end = self.__new_state()
- for end in ends:
- end.add_epsilon_transition(new_end)
- return (start, [new_end])
+ def __catch_all(self, graph):
+ return self.__key_state(TransitionKey.unique('catch_all'))
def __join(self, graph):
(graph, name, subgraph, modifier) = graph[1:]
@@ -303,8 +318,12 @@ class NfaBuilder:
return ('CONTINUE', graph)
@staticmethod
- def add_break(graph):
- return ('BREAK', graph)
+ def catch_all():
+ return ('CATCH_ALL',)
+
+ @staticmethod
+ def epsilon():
+ return ('EPSILON',)
@staticmethod
def join_subgraph(graph, name, subgraph, modifier):
@@ -413,6 +432,7 @@ class Nfa(Automaton):
def compute_dfa(self):
self.__compute_epsilon_closures()
+ self.__visit_all_edges(lambda node, state: node.replace_catch_all(), None)
dfa_nodes = {}
start_name = self.__to_dfa(set([self.__start]), dfa_nodes, self.__end)
return (start_name, dfa_nodes)

Powered by Google App Engine
This is Rietveld 408576698