X-Git-Url: http://git.tremily.us/?a=blobdiff_plain;f=Cython%2FPlex%2FTransitions.py;h=8ed55148d564cdca7c5251d57fe63d19dc5c02d9;hb=f6762fad87f8d4ab0341281381b7d49c494fe6a2;hp=98d5a286df8e48b06b1b1939dc0f860ec08df8fa;hpb=671e6a53a4621f5a684f45ed9e4436e74af9975e;p=cython.git diff --git a/Cython/Plex/Transitions.py b/Cython/Plex/Transitions.py index 98d5a286..8ed55148 100644 --- a/Cython/Plex/Transitions.py +++ b/Cython/Plex/Transitions.py @@ -11,34 +11,34 @@ from sys import maxint as maxint class TransitionMap(object): """ A TransitionMap maps an input event to a set of states. - An input event is one of: a range of character codes, - the empty string (representing an epsilon move), or one + An input event is one of: a range of character codes, + the empty string (representing an epsilon move), or one of the special symbols BOL, EOL, EOF. - - For characters, this implementation compactly represents + + For characters, this implementation compactly represents the map by means of a list: - + [code_0, states_0, code_1, states_1, code_2, states_2, ..., code_n-1, states_n-1, code_n] - - where |code_i| is a character code, and |states_i| is a + + where |code_i| is a character code, and |states_i| is a set of states corresponding to characters with codes |c| in the range |code_i| <= |c| <= |code_i+1|. - + The following invariants hold: n >= 1 code_0 == -maxint code_n == maxint code_i < code_i+1 for i in 0..n-1 states_0 == states_n-1 - + Mappings for the special events '', BOL, EOL, EOF are kept separately in a dictionary. """ - + map = None # The list of codes and states special = None # Mapping for special events - + def __init__(self, map = None, special = None): if not map: map = [-maxint, {}, maxint] @@ -47,7 +47,7 @@ class TransitionMap(object): self.map = map self.special = special #self.check() ### - + def add(self, event, new_state, TupleType = tuple): """ @@ -79,14 +79,14 @@ class TransitionMap(object): i = i + 2 else: self.get_special(event).update(new_set) - + def get_epsilon(self, none = None): """ Return the mapping for epsilon, or None. """ return self.special.get('', none) - + def iteritems(self, len = len): """ @@ -111,14 +111,14 @@ class TransitionMap(object): result.append((event, set)) return iter(result) items = iteritems - + # ------------------- Private methods -------------------- def split(self, code, len = len, maxint = maxint): """ - Search the list for the position of the split point for |code|, - inserting a new split point if necessary. Returns index |i| such + Search the list for the position of the split point for |code|, + inserting a new split point if necessary. Returns index |i| such that |code| == |map[i]|. """ # We use a funky variation on binary search. @@ -144,7 +144,7 @@ class TransitionMap(object): map[hi:hi] = [code, map[hi - 1].copy()] #self.check() ### return hi - + def get_special(self, event): """ Get state set for special event, adding a new entry if necessary. @@ -157,7 +157,7 @@ class TransitionMap(object): return set # --------------------- Conversion methods ----------------------- - + def __str__(self): map_strs = [] map = self.map @@ -183,15 +183,15 @@ class TransitionMap(object): ','.join(map_strs), special_strs ) - + # --------------------- Debugging methods ----------------------- - + def check(self): """Check data structure integrity.""" if not self.map[-3] < self.map[-1]: print(self) assert 0 - + def dump(self, file): map = self.map i = 0 @@ -204,7 +204,7 @@ class TransitionMap(object): if not event: event = 'empty' self.dump_trans(event, set, file) - + def dump_range(self, code0, code1, set, file): if set: if code0 == -maxint: @@ -217,19 +217,19 @@ class TransitionMap(object): elif code0 == code1 - 1: k = self.dump_char(code0) else: - k = "%s..%s" % (self.dump_char(code0), + k = "%s..%s" % (self.dump_char(code0), self.dump_char(code1 - 1)) self.dump_trans(k, set, file) - + def dump_char(self, code): if 0 <= code <= 255: return repr(chr(code)) else: return "chr(%d)" % code - + def dump_trans(self, key, set, file): file.write(" %s --> %s\n" % (key, self.dump_set(set))) - + def dump_set(self, set): return state_set_str(set) @@ -243,6 +243,6 @@ class TransitionMap(object): def state_set_str(set): return "[%s]" % ','.join(["S%d" % state.number for state in set]) - - + +