def _get_loop_map(TheCountMap, SmList, IidLoopExit): """A loop map tells about the behavior of the core loop. It tells what needs to happen as a consequence to an incoming character. Two options: -- Return to loop (normal case) -- Enter the tail (appendix) of a parallel state machine. RETURNS: List of LoopMapEntry-s. A LoopMapEntry consists of: .character_set: Character set that triggers. .count_action: Count action related to the character set. == None, if the character set causes 'loop exit'. .incidence_id: Incidence Id of terminal that is triggered by character set. -- incidence id of count action terminal, or -- incidence id of couple terminal. .appendix_sm: Appendix state machine -- combined appendix state machines, or -- None, indicating that there is none. """ L = TheCountMap.loop_character_set() # 'couple_list': Transitions to 'couple terminals' # => connect to appendix state machines couple_list, \ appendix_sm_list = _get_LoopMapEntry_list_parallel_state_machines(TheCountMap, SmList) L_couple = NumberSet.from_union_of_iterable( lei.character_set for lei in couple_list ) # 'plain_list': Transitions to 'normal terminals' # => perform count action and loop. L_plain = L.difference(L_couple) plain_list = _get_LoopMapEntry_list_plain(TheCountMap, L_plain) # 'L_exit': Transition to exit # => remaining characters cause exit. L_loop = NumberSet.from_union_of_iterable( x.character_set for x in chain(couple_list, plain_list) ) universal_set = Setup.buffer_codec.source_set L_exit = L_loop.get_complement(universal_set) exit_list = [ LoopMapEntry(L_exit, None, IidLoopExit, None) ] result = couple_list + plain_list + exit_list assert not any(lei is None for lei in result) assert not any(lei.character_set is None for lei in result) assert not any(lei.incidence_id is None for lei in result) return result, appendix_sm_list
def _get_loop_map(TheCountMap, SmList, IidLoopExit): """A loop map tells about the behavior of the core loop. It tells what needs to happen as a consequence to an incoming character. Two options: -- Return to loop (normal case) -- Enter the tail (appendix) of a parallel state machine. RETURNS: List of LoopMapEntry-s. A LoopMapEntry consists of: .character_set: Character set that triggers. .count_action: Count action related to the character set. == None, if the character set causes 'loop exit'. .incidence_id: Incidence Id of terminal that is triggered by character set. -- incidence id of count action terminal, or -- incidence id of couple terminal. .appendix_sm: Appendix state machine -- combined appendix state machines, or -- None, indicating that there is none. """ L = TheCountMap.loop_character_set() # 'couple_list': Transitions to 'couple terminals' # => connect to appendix state machines couple_list, \ appendix_sm_list = _get_LoopMapEntry_list_parallel_state_machines(TheCountMap, SmList) L_couple = NumberSet.from_union_of_iterable(lei.character_set for lei in couple_list) # 'plain_list': Transitions to 'normal terminals' # => perform count action and loop. L_plain = L.difference(L_couple) plain_list = _get_LoopMapEntry_list_plain(TheCountMap, L_plain) # 'L_exit': Transition to exit # => remaining characters cause exit. L_loop = NumberSet.from_union_of_iterable( x.character_set for x in chain(couple_list, plain_list)) universal_set = Setup.buffer_codec.source_set L_exit = L_loop.get_complement(universal_set) exit_list = [LoopMapEntry(L_exit, None, IidLoopExit, None)] result = couple_list + plain_list + exit_list assert not any(lei is None for lei in result) assert not any(lei.character_set is None for lei in result) assert not any(lei.incidence_id is None for lei in result) return result, appendix_sm_list
def get_incidence_id_map(self, BeyondIncidenceId=None): """RETURNS: A list of pairs: (character_set, incidence_id) All same counting actions are referred to by the same incidence id. If BeyondIncidenceId is given, then the remaining set of characters is associated with 'BeyondIncidenceId'. """ result = [ (x.character_set, x.incidence_id) for x in self.__map ] if BeyondIncidenceId is None: return result all_set = NumberSet.from_union_of_iterable(x.character_set for x in self.__map) beyond_set = all_set.get_complement(Setup.buffer_codec.source_set) if not beyond_set.is_empty(): result.append((beyond_set, BeyondIncidenceId)) return result
def get_incidence_id_map(self, BeyondIncidenceId=None): """RETURNS: A list of pairs: (character_set, incidence_id) All same counting actions are referred to by the same incidence id. If BeyondIncidenceId is given, then the remaining set of characters is associated with 'BeyondIncidenceId'. """ result = [(x.character_set, x.incidence_id) for x in self.__map] if BeyondIncidenceId is None: return result all_set = NumberSet.from_union_of_iterable(x.character_set for x in self.__map) beyond_set = all_set.get_complement(Setup.buffer_codec.source_set) if not beyond_set.is_empty(): result.append((beyond_set, BeyondIncidenceId)) return result
def _get_loop_map(loop_config, CaMap, SmList, IidLoopExit, L_subset): """A loop map tells about the behavior of the core loop. It tells what needs to happen as a consequence to an incoming character. Two options: L_subset = NumberSet containing characters that are actually part of the loop. 'None' => all characters of 'CaMap' are considered. -- Return to loop (normal case) -- Enter the tail (appendix) of a parallel state machine. RETURNS: List of LoopMapEntry-s. A LoopMapEntry consists of: .character_set: Character set that triggers. .count_action: Count action related to the character set. == None, if the character set causes 'loop exit'. .iid_couple_terminal: Incidence Id of terminal that is triggered by character set. -- incidence id of count action terminal, or -- incidence id of couple terminal. .appendix_sm: Appendix state machine -- combined appendix state machines, or -- None, indicating that there is none. """ assert all( _state_machine_tagged_with_matching_incidence_ids(sm) for sm in SmList) # State machines are not to be transformed at this point in time assert all(not _exists_bad_lexatom_detector_state(sm) for sm in SmList) CaMap.prune(Setup.buffer_encoding.source_set) L = CaMap.union_of_all() L_couple = NumberSet.from_union_of_iterable( sm.get_beginning_character_set() for sm in SmList) # 'plain_list': Transitions to 'normal terminals' # => perform count action and loop. L_plain = L.difference(L_couple) if L_subset is not None: L_plain.intersect_with(L_subset) L_loop = L_plain.union(L_couple) L_exit = L_loop.get_complement(Setup.buffer_encoding.source_set) plain_list = _get_LoopMapEntry_list_plain(loop_config, CaMap, L_plain) exit_list = [] if not L_exit.is_empty(): exit_list.append( LoopMapEntry(L_exit, IidLoopExit, Code=loop_config.cmd_list_CA_GotoTerminal( None, IidLoopExit))) # 'couple_list': Transitions to 'couple terminals' # => connect to appendix state machines couple_list, \ combined_appendix_sm_list, \ appendix_cmd_list_db = parallel_state_machines.do(loop_config, CaMap, SmList) assert L_couple.is_equal( NumberSet.from_union_of_iterable(lei.character_set for lei in couple_list)) result = LoopMap( couple_list, # --> jump to appendix sm-s plain_list, # --> iterate to loop start exit_list) # --> exit loop return result, combined_appendix_sm_list, appendix_cmd_list_db
def union_of_all(self): return NumberSet.from_union_of_iterable( number_set for number_set, ca in self )
def loop_character_set(self): return NumberSet.from_union_of_iterable(x.character_set for x in self.__map)
def loop_character_set(self): return NumberSet.from_union_of_iterable(x.character_set for x in self.__map)