def do(txt, TransitionMap, StateIndex=None, EngineType=E_EngineTypes.FORWARD, InitStateF=False, GotoReload_Str=None, TheAnalyzer=None): global LanguageDB assert isinstance(TransitionMap, list) assert EngineType in E_EngineTypes assert isinstance(InitStateF, bool) assert StateIndex is None or isinstance(StateIndex, long) assert GotoReload_Str is None or isinstance(GotoReload_Str, (str, unicode)) transition_map_tools.assert_adjacency(TransitionMap) # If a state has no transitions, no new input needs to be eaten => no reload. # # NOTE: The only case where the buffer reload is not required are empty states, # AND states during backward input position detection! if len(TransitionMap) == 0: return LanguageDB = Setup.language_db # The range of possible characters may be restricted. It must be ensured, # that the occurring characters only belong to the admissible range. solution.prune_range(TransitionMap) # The 'buffer-limit-code' always needs to be identified separately. # This helps to generate the reload procedure a little more elegantly. # (Backward input position detection does not reload. It only moves # inside the current lexeme, which must be inside the buffer.) if EngineType != E_EngineTypes.BACKWARD_INPUT_POSITION: __separate_buffer_limit_code_transition(TransitionMap, EngineType) # All transition information related to intervals become proper objects of # class TransitionCode. transition_map = [(entry[0], transition_code.do(entry[1], StateIndex, InitStateF, EngineType, GotoReload_Str, TheAnalyzer)) for entry in TransitionMap] # transition_map = SubTriggerMap(transition_map) #__________________________________________________________________________ # (*) Determine 'outstanding' transitions and take them # out of the map. outstanding = solution.prune_outstanding(transition_map) if outstanding is not None: __get_outstanding(outstanding) # (*) Bisection until other solution is more suitable. # (This may include 'no bisectioning') __bisection(txt, transition_map) # (*) When there was an outstanding character, then the whole bisection was # implemented in an 'ELSE' block which must be closed. if outstanding is not None: txt.append(LanguageDB.ENDIF)
def do(txt, TransitionMap, StateIndex = None, EngineType = E_EngineTypes.FORWARD, InitStateF = False, GotoReload_Str = None, TheAnalyzer = None): global LanguageDB assert isinstance(TransitionMap, list) assert EngineType in E_EngineTypes assert isinstance(InitStateF, bool) assert StateIndex is None or isinstance(StateIndex, long) assert GotoReload_Str is None or isinstance(GotoReload_Str, (str, unicode)) transition_map_tools.assert_adjacency(TransitionMap) # If a state has no transitions, no new input needs to be eaten => no reload. # # NOTE: The only case where the buffer reload is not required are empty states, # AND states during backward input position detection! if len(TransitionMap) == 0: return LanguageDB = Setup.language_db # The range of possible characters may be restricted. It must be ensured, # that the occurring characters only belong to the admissible range. solution.prune_range(TransitionMap) # The 'buffer-limit-code' always needs to be identified separately. # This helps to generate the reload procedure a little more elegantly. # (Backward input position detection does not reload. It only moves # inside the current lexeme, which must be inside the buffer.) if EngineType != E_EngineTypes.BACKWARD_INPUT_POSITION: __separate_buffer_limit_code_transition(TransitionMap, EngineType) # All transition information related to intervals become proper objects of # class TransitionCode. transition_map = [ (entry[0], transition_code.do(entry[1], StateIndex, InitStateF, EngineType, GotoReload_Str, TheAnalyzer)) for entry in TransitionMap ] # transition_map = SubTriggerMap(transition_map) #__________________________________________________________________________ # (*) Determine 'outstanding' transitions and take them # out of the map. outstanding = solution.prune_outstanding(transition_map) if outstanding is not None: __get_outstanding(outstanding) # (*) Bisection until other solution is more suitable. # (This may include 'no bisectioning') __bisection(txt, transition_map) # (*) When there was an outstanding character, then the whole bisection was # implemented in an 'ELSE' block which must be closed. if outstanding is not None: txt.append(LanguageDB.ENDIF)
def combine_maps(StateA, StateB): """RETURNS: -- Transition map = combined transition map of StateA and StateB. -- List of target schemes that have been identified. NOTE: If the entries of both states are uniform, then a transition to itself of both states can be implemented as a recursion of the template state without knowing the particular states. EXPLANATION: This function combines two transition maps. A transition map is a list of tuples: [ ... (interval, target) ... ] Each tuple tells about a character range [interval.begin, interval.end) where the state triggers to the given target. In a normal AnalyzerState the target is the index of the target state. In a TemplateState, though, multiple states are combined. A TemplateState operates on behalf of a state which is identified by its 'state_key'. If two states (even TemplateStates) are combined the trigger maps are observed, e.g. Trigger Map A Trigger Map B [ [ ([0, 10), DropOut) ([0, 10), State_4) ([10, 15), State_0) ([10, 15), State_1) ([15, 20), DropOut) ([15, 20), State_0) ([20, 21), State_1) ([20, 21), DropOut) ([21, 255), DropOut) ([21, 255), State_0) ] ] For some intervals, the target is the same. But for some it is different. In a TemplateState, the intervals are associated with MegaState_Target objects. A MegaState_Target object tells the target state dependent on the 'state_key'. The above example may result in a transition map as below: Trigger Map A [ # intervals: target schemes: ( [0, 10), { A: DropOut, B: State_4, }, ( [10, 15), { A: State_0, B: State_1, }, ( [15, 20), { A: DropOut, B: State_0, }, ( [20, 21), { A: State_1, B: DropOut, }, ( [21, 255), { A: DropOut, B: State_0, }, ] Note, that the 'scheme' for interval [12, 20) and [21, 255) are identical. We try to profit from it by storing only it only once. A template scheme is associated with an 'index' for reference. TemplateStates may be combined with AnalyzerStates and other TemplateStates. Thus, MegaState_Targets must be combined with trigger targets and other MegaState_Targets. NOTE: The resulting target map results from the combination of both transition maps, which may introduce new borders, e.g. |----------------| (where A triggers to X) |---------------| (where B triggers to Y) becomes |----|-----------|---| 1 2 3 where: Domain: A triggers to: B triggers to: 1 X Nothing 2 X Y 3 Nothing Y ----------------------------------------------------------------------------- Transition maps of TemplateState-s function based on 'state_keys'. Those state keys are used as indices into TemplateMegaState_Targets. The 'state_key' of a given state relates to the 'state_index' by (1) self.state_index_sequence[state_key] == state_index where 'state_index' is the number by which the state is identified inside its state machine. Correspondingly, for a given TemplateMegaState_Target T (2) T[state_key] gives the target of the template if it operates for 'state_index' determined from 'state_key' by relation (1). The state index list approach facilitates the computation of target schemes. For this reason no dictionary {state_index->target} is used. """ transition_map_tools.assert_adjacency(StateA.transition_map, TotalRangeF=True) transition_map_tools.assert_adjacency(StateB.transition_map, TotalRangeF=True) MegaState_Target.init( ) # Initialize the tracking of generated MegaState_Target-s factory = TargetFactory(StateA, StateB) result = [] for begin, end, a_target, b_target in transition_map_tools.zipped_iterable( StateA.transition_map, StateB.transition_map): target = factory.get(a_target, b_target) result.append((Interval(begin, end), target)) # Return the database of generated MegaState_Target objects mega_state_target_db = MegaState_Target.disconnect_object_db() # Number of different target schemes: scheme_n = 0 for x in (key for key in mega_state_target_db.iterkeys() if isinstance(key, tuple)): scheme_n += 1 return result, scheme_n
def combine_maps(StateA, StateB): """RETURNS: -- Transition map = combined transition map of StateA and StateB. -- List of target schemes that have been identified. NOTE: If the entries of both states are uniform, then a transition to itself of both states can be implemented as a recursion of the template state without knowing the particular states. EXPLANATION: This function combines two transition maps. A transition map is a list of tuples: [ ... (interval, target) ... ] Each tuple tells about a character range [interval.begin, interval.end) where the state triggers to the given target. In a normal AnalyzerState the target is the index of the target state. In a TemplateState, though, multiple states are combined. A TemplateState operates on behalf of a state which is identified by its 'state_key'. If two states (even TemplateStates) are combined the trigger maps are observed, e.g. Trigger Map A Trigger Map B [ [ ([0, 10), DropOut) ([0, 10), State_4) ([10, 15), State_0) ([10, 15), State_1) ([15, 20), DropOut) ([15, 20), State_0) ([20, 21), State_1) ([20, 21), DropOut) ([21, 255), DropOut) ([21, 255), State_0) ] ] For some intervals, the target is the same. But for some it is different. In a TemplateState, the intervals are associated with MegaState_Target objects. A MegaState_Target object tells the target state dependent on the 'state_key'. The above example may result in a transition map as below: Trigger Map A [ # intervals: target schemes: ( [0, 10), { A: DropOut, B: State_4, }, ( [10, 15), { A: State_0, B: State_1, }, ( [15, 20), { A: DropOut, B: State_0, }, ( [20, 21), { A: State_1, B: DropOut, }, ( [21, 255), { A: DropOut, B: State_0, }, ] Note, that the 'scheme' for interval [12, 20) and [21, 255) are identical. We try to profit from it by storing only it only once. A template scheme is associated with an 'index' for reference. TemplateStates may be combined with AnalyzerStates and other TemplateStates. Thus, MegaState_Targets must be combined with trigger targets and other MegaState_Targets. NOTE: The resulting target map results from the combination of both transition maps, which may introduce new borders, e.g. |----------------| (where A triggers to X) |---------------| (where B triggers to Y) becomes |----|-----------|---| 1 2 3 where: Domain: A triggers to: B triggers to: 1 X Nothing 2 X Y 3 Nothing Y ----------------------------------------------------------------------------- Transition maps of TemplateState-s function based on 'state_keys'. Those state keys are used as indices into TemplateMegaState_Targets. The 'state_key' of a given state relates to the 'state_index' by (1) self.state_index_sequence[state_key] == state_index where 'state_index' is the number by which the state is identified inside its state machine. Correspondingly, for a given TemplateMegaState_Target T (2) T[state_key] gives the target of the template if it operates for 'state_index' determined from 'state_key' by relation (1). The state index list approach facilitates the computation of target schemes. For this reason no dictionary {state_index->target} is used. """ transition_map_tools.assert_adjacency(StateA.transition_map, TotalRangeF=True) transition_map_tools.assert_adjacency(StateB.transition_map, TotalRangeF=True) MegaState_Target.init() # Initialize the tracking of generated MegaState_Target-s factory = TargetFactory(StateA, StateB) result = [] for begin, end, a_target, b_target in transition_map_tools.zipped_iterable(StateA.transition_map, StateB.transition_map): target = factory.get(a_target, b_target) result.append((Interval(begin, end), target)) # Return the database of generated MegaState_Target objects mega_state_target_db = MegaState_Target.disconnect_object_db() # Number of different target schemes: scheme_n = 0 for x in (key for key in mega_state_target_db.iterkeys() if isinstance(key, tuple)): scheme_n += 1 return result, scheme_n