Exemple #1
0
    def add_state(self, StateIndex, OnSuccessDoorId, OnFailureDoorId, BeforeReload=None):
        """Adds a state from where the reload state is entered. When reload is
        done it jumps to 'OnFailureDoorId' if the reload failed and to 'OnSuccessDoorId'
        if the reload succeeded.

        RETURNS: DoorID into the reload state. Jump to this DoorID in order
                 to trigger the reload for the state given by 'StateIndex'.
        """
        assert BeforeReload is None or isinstance(BeforeReload, OpList) 
        # Before reload: prepare after reload, the jump back to the reloading state.
        before_cl = OpList(Op.PrepareAfterReload(OnSuccessDoorId, OnFailureDoorId))
        if BeforeReload is not None:
            # May be, add additional commands
            before_cl = before_cl.concatinate(BeforeReload)

        # No two transitions into the reload state have the same OpList!
        # No two transitions can have the same DoorID!
        # => it is safe to assign a new DoorID withouth .categorize()
        ta         = TransitionAction(before_cl)
        # Assign a DoorID (without categorization) knowing that no such entry
        # into this state existed before.
        ta.door_id = dial_db.new_door_id(self.index)

        assert not self.entry.has_transition(self.index, StateIndex) # Cannot be in there twice!
        self.entry.enter(self.index, StateIndex, ta)

        return ta.door_id
Exemple #2
0
def get_Analyzer(StatesDescription):
    """StatesDescription: List of pairs:
         
           (state index, transition map)

       That is, it tells what state of a given state index has what transition
       map. The transition map is a list of pairs

           (interval, target state index)
    """
    # Use 'BACKWARD_PRE_CONTEXT' so that the drop-out objects are created
    # without larger analysis.
    init_state_index = 7777L
    analyzer = Analyzer(engine.BACKWARD_PRE_CONTEXT, init_state_index)
    all_state_index_set = set()
    for state_index, transition_map in StatesDescription:
        assert isinstance(state_index, long)
        assert isinstance(transition_map, list)
        tm = TransitionMap.from_iterable(transition_map)
        tm.fill_gaps(E_StateIndices.DROP_OUT,
                     Setup.buffer_codec.drain_set.minimum(),
                     Setup.buffer_codec.drain_set.supremum())
        analyzer.state_db[state_index] = get_AnalyzerState(state_index, tm)
        all_state_index_set.update(x[1] for x in transition_map)

    # 'Dummy' transitions from init state to all
    analyzer.state_db[init_state_index] = get_AnalyzerState_Init(
        init_state_index, [x[0] for x in StatesDescription])

    # Make sure, that all states mentioned in the transition map really exist.
    for i in all_state_index_set:
        if i in analyzer.state_db: continue
        analyzer.state_db[i] = get_AnalyzerState(
            i, TransitionMap.from_iterable([]))

    # Make sure, that the transitions appear in the 'entry' member of the
    # states. Collect transition information.
    for state_index, transition_map in StatesDescription:
        for interval, target_index in transition_map:
            if not isinstance(target_index, (long, int)): continue
            analyzer.state_db[target_index].entry.enter(
                target_index, state_index, TransitionAction())
        analyzer.state_db[state_index].entry.enter(state_index,
                                                   init_state_index,
                                                   TransitionAction())

    for state in analyzer.state_db.itervalues():
        state.entry.categorize(state.index)

    # Make sure that every state has its entry into drop-out
    empty_cl = OpList()
    for i in analyzer.state_db.iterkeys():
        analyzer.drop_out.entry.enter_OpList(E_StateIndices.DROP_OUT, i,
                                             copy(empty_cl))
    analyzer.drop_out.entry.categorize(E_StateIndices.DROP_OUT)

    analyzer.prepare_DoorIDs()

    return analyzer
Exemple #3
0
    def prepare_state(self, OldState, StateIndex, OnBeforeEntry):
        """Prepares states to increment the input/read pointer and dereferences it
        to access the lexatom for the state transition triggering.
        
        REQUIRES: 'self.init_state_forward_f', 'self.engine_type', 'self.__from_db'.
        """
        state = FSM_State.from_State(OldState, StateIndex, self.engine_type,
                                     self.dial_db)

        cmd_list = []
        if self.engine_type.is_BACKWARD_PRE_CONTEXT():
            cmd_list.extend(
                Op.PreContextOK(cmd.acceptance_id())
                for cmd in OldState.single_entry.get_iterable(SeAccept))

        if state.transition_map is None and False:
            # NOTE: We need a way to disable this exception for PathWalkerState-s(!)
            #       It's safe, not to allow it, in general.
            #------------------------------------------------------------------------
            # If the state has no further transitions then the input character does
            # not have to be read. This is so, since without a transition map, the
            # state immediately drops out. The drop out transits to a terminal.
            # Then, the next action will happen from the init state where we work
            # on the same position. If required the reload happens at that moment,
            # NOT before the empty transition block.
            #
            # This is not true for Path Walker States, so we offer the option
            # 'ForceInputDereferencingF'
            assert StateIndex != self.init_state_index  # Empty state machine! --> impossible

            if self.engine_type.is_FORWARD():
                cmd_ext = [Op.Increment(E_R.InputP)]
            else:
                cmd_ext = [Op.Decrement(E_R.InputP)]
        else:
            if self.engine_type.is_FORWARD():
                cmd_ext = [Op.Increment(E_R.InputP), Op.InputPDereference()]
            else:
                cmd_ext = [Op.Decrement(E_R.InputP), Op.InputPDereference()]

        cmd_list.extend(cmd_ext)

        ta = TransitionAction(OpList.from_iterable(cmd_list))

        # NOTE: The 'from reload transition' is implemented by 'prepare_for_reload()'
        for source_state_index in self.__from_db[StateIndex]:
            assert source_state_index != E_StateIndices.BEFORE_ENTRY
            state.entry.enter(StateIndex, source_state_index, ta.clone())

        if StateIndex == self.init_state_index:
            if self.engine_type.is_FORWARD():
                on_entry_op_list = OnBeforeEntry.clone()
                on_entry_op_list.append(Op.InputPDereference())
                ta = TransitionAction(on_entry_op_list)
            state.entry.enter_state_machine_entry(self.__state_machine_id,
                                                  StateIndex, ta)

        return state
Exemple #4
0
    def prepare_state(self, OldState, StateIndex, OnBeforeEntry):
        """REQUIRES: 'self.init_state_forward_f', 'self.engine_type', 'self.__from_db'.
        """
        state = AnalyzerState.from_State(OldState, StateIndex, self.engine_type)

        cmd_list = []
        if self.engine_type.is_BACKWARD_PRE_CONTEXT():
            cmd_list.extend(
                 Op.PreContextOK(cmd.acceptance_id()) 
                 for cmd in OldState.single_entry.get_iterable(SeAccept)
            )

        if state.transition_map is None and False: 
            # NOTE: We need a way to disable this exception for PathWalkerState-s(!)
            #       It's safe, not to allow it, in general.
            #------------------------------------------------------------------------
            # If the state has no further transitions then the input character does 
            # not have to be read. This is so, since without a transition map, the 
            # state immediately drops out. The drop out transits to a terminal. 
            # Then, the next action will happen from the init state where we work
            # on the same position. If required the reload happens at that moment,
            # NOT before the empty transition block.
            #
            # This is not true for Path Walker States, so we offer the option 
            # 'ForceInputDereferencingF'
            assert StateIndex != self.init_state_index # Empty state machine! --> impossible

            if self.engine_type.is_FORWARD(): 
                cmd_ext = [ Op.Increment(E_R.InputP) ]
            else:                             
                cmd_ext = [ Op.Decrement(E_R.InputP) ]
        else:
            if self.engine_type.is_FORWARD(): 
                cmd_ext = [ Op.Increment(E_R.InputP), Op.InputPDereference() ]
            else:                             
                cmd_ext = [ Op.Decrement(E_R.InputP), Op.InputPDereference() ]

        cmd_list.extend(cmd_ext)

        ta = TransitionAction(OpList.from_iterable(cmd_list))

        # NOTE: The 'from reload transition' is implemented by 'prepare_for_reload()'
        for source_state_index in self.__from_db[StateIndex]: 
            assert source_state_index != E_StateIndices.BEFORE_ENTRY
            state.entry.enter(StateIndex, source_state_index, ta.clone())

        if StateIndex == self.init_state_index:
            if self.engine_type.is_FORWARD():
                on_entry_op_list = OnBeforeEntry.clone()
                on_entry_op_list.append(Op.InputPDereference())
                ta = TransitionAction(on_entry_op_list)
            state.entry.enter_state_machine_entry(self.__state_machine_id, 
                                                  StateIndex, ta)

        return state
Exemple #5
0
    def prepare_state(self, OldState, StateIndex):
        """REQUIRES: 'self.init_state_forward_f', 'self.engine_type', 'self.__from_db'.
        """
        state = AnalyzerState.from_State(OldState, StateIndex,
                                         self.engine_type)

        cmd_list = []
        if self.engine_type.is_BACKWARD_PRE_CONTEXT():
            cmd_list.extend(
                 PreContextOK(origin.acceptance_id()) for origin in OldState.origins() \
                 if origin.is_acceptance()
            )

        if state.transition_map is None and False:
            # NOTE: We need a way to disable this exception for PathWalkerState-s(!)
            #       It's safe, not to allow it, in general.
            #------------------------------------------------------------------------
            # If the state has no further transitions then the input character does
            # not have to be read. This is so, since without a transition map, the
            # state immediately drops out. The drop out transits to a terminal.
            # Then, the next action will happen from the init state where we work
            # on the same position. If required the reload happens at that moment,
            # NOT before the empty transition block.
            #
            # This is not true for Path Walker States, so we offer the option
            # 'ForceInputDereferencingF'
            assert StateIndex != self.init_state_index  # Empty state machine! --> impossible

            if self.engine_type.is_FORWARD():
                cmd_list.append(InputPIncrement())
            else:
                cmd_list.append(InputPDecrement())
        else:
            if self.engine_type.is_FORWARD():
                cmd_list.extend([InputPIncrement(), InputPDereference()])
            else:
                cmd_list.extend([InputPDecrement(), InputPDereference()])

        ta = TransitionAction(CommandList.from_iterable(cmd_list))

        # NOTE: The 'from reload transition' is implemented by 'prepare_for_reload()'
        for source_state_index in self.__from_db[StateIndex]:
            assert source_state_index != E_StateIndices.NONE
            state.entry.enter(StateIndex, source_state_index, ta.clone())

        if StateIndex == self.init_state_index:
            if self.engine_type.is_FORWARD():
                ta = TransitionAction(CommandList(InputPDereference()))
            state.entry.enter_state_machine_entry(self.__state_machine_id,
                                                  StateIndex, ta)

        return state
Exemple #6
0
def group(CharacterPathList, TheAnalyzer, CompressionType):
    """Different character paths may be walked down by the same pathwalker, if
    certain conditions are met. This function groups the given list of
    character paths and assigns them to PathWalkerState-s. The
    PathWalkerState-s can then immediately be used for code generation.  
    """
    path_walker_list = []
    for candidate in CharacterPathList:
        for path_walker in path_walker_list:
            # Set-up the walk in an existing PathWalkerState
            if path_walker.accept(candidate, TheAnalyzer.state_db): break
        else:
            # Create a new PathWalkerState
            path_walker_list.append(
                PathWalkerState(candidate, TheAnalyzer, CompressionType))

    absorbance_db = defaultdict(set)
    for path_walker in path_walker_list:
        absorbance_db.update(
            (i, path_walker)
            for i in path_walker.implemented_state_index_list())

        if path_walker.uniform_entry_command_list_along_all_paths is not None:
            # Assign the uniform command list to the transition 'path_walker -> path_walker'
            transition_action = TransitionAction(
                path_walker.index, path_walker.index,
                path_walker.uniform_entry_command_list_along_all_paths)
            # Delete transitions on the path itself => No doors for them will be implemented.
            path_walker.delete_transitions_on_path(
            )  # LEAVE THIS! This is the way to
            #                                        # indicate unimportant entry doors!
        else:
            # Nothing special to be done upon iteration over the path
            transition_action = TransitionAction(path_walker.index,
                                                 path_walker.index)

        transition_id = TransitionID(path_walker.index, path_walker.index)
        path_walker.entry.action_db[transition_id] = transition_action

        # Once the entries are combined, re-configure the door tree
        path_walker.entry.door_tree_configure()

    return absorbance_db
Exemple #7
0
    def add_mega_state(self, MegaStateIndex, StateKeyRegister, Iterable_StateKey_Index_Pairs, 
                       TheAnalyzer):
        """Implement a router from the MegaState-s door into the Reloader to
        the doors of the implemented states. 
        
                        Reload State
                       .--------------------------------- - -  -
                     .--------------.    on state-key
          reload --->| MegaState's  |       .---.
                     | Reload Door  |------>| 0 |-----> Reload Door of state[0]
                     '--------------'       | 1 |-----> Reload Door of state[1]
                       |                    | : |
                       :                    '---'
                       '--------------------------------- - -  -

        """
        def DoorID_provider(state_index):
            door_id = self.entry.get_door_id(self.index, state_index)
            if door_id is None:
                # The state implemented in the MegaState did not have a 
                # transition to 'ReloadState'. Thus, it was a total drop-out.
                # => Route to the state's drop-out.
                door_id = TheAnalyzer.drop_out_DoorID(state_index)
            return door_id

        cmd = Op.RouterOnStateKey(
            StateKeyRegister, MegaStateIndex,
            Iterable_StateKey_Index_Pairs,
            DoorID_provider
        )

        ta         = TransitionAction(OpList(cmd))
        # Assign a DoorID (without categorization) knowing that no such entry
        # into this state existed before.
        ta.door_id = dial_db.new_door_id(self.index)

        assert not self.entry.has_transition(self.index, MegaStateIndex) # Cannot be in there twice!
        self.entry.enter(self.index, MegaStateIndex, ta)

        return ta.door_id
Exemple #8
0
    def __init__(self, StateIndex, FromStateIndexList, PreContextFulfilledID_List=None):
        # map:  (from_state_index) --> list of actions to be taken if state is entered 
        #                              'from_state_index' for a given pre-context.
        # if len(FromStateIndexList) == 0: FromStateIndexList = [ E_StateIndices.NONE ]
        self.__state_index = StateIndex
        self.__action_db   = dict((TransitionID(StateIndex, i),     \
                                   TransitionAction(StateIndex, i)) \
                                   for i in FromStateIndexList)

        # Are the actions for all doors the same?
        self.__uniform_doors_f = None 

        # Function 'categorize_command_lists()' fills the following members
        self.__door_db        = None # map: transition_id --> door_id
        self.__transition_db  = None # map: door_id       --> transition_id
        self.__door_tree_root = None # The root of the door tree.

        # Only for 'Backward Detecting Pre-Contexts'.
        if PreContextFulfilledID_List is not None:
            pre_context_ok_command_list = [ entry_action.PreConditionOK(pre_context_id) \
                                           for pre_context_id in PreContextFulfilledID_List ]
            for entry in self.__action_db.itervalues():
                entry.command_list.misc.update(pre_context_ok_command_list)
Exemple #9
0
 def enter_OpList(self, ToStateIndex, FromStateIndex, Cl):
     return self.enter(ToStateIndex, FromStateIndex, TransitionAction(Cl))