Пример #1
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
Пример #2
0
def _get_state_machine_vs_terminal_list(CloserSequence, OpenerSequence,
                                        CounterDb, DoorIdAfter):
    """Additionally to all characters, the loop shall walk along the 'closer'.
    If the closer matches, the range skipping exits. Characters need to be 
    counted properly.

    RETURNS: list(state machine, terminal)

    The list contains only one single element.
    """
    # Opener Sequence Reaction
    opener_op_list = [Op.Increment(E_R.Counter)]
    # 'Goto loop entry' is added later (loop id unknown, yet).

    # Closer Sequence Reaction
    closer_op_list = [
        Op.Decrement(E_R.Counter),
        Op.GotoDoorIdIfCounterEqualZero(DoorIdAfter)
    ]
    # 'Goto loop entry' is added later (loop id unknown, yet).

    return [
        _get_state_machine_and_terminal(OpenerSequence,
                                        "<SKIP NESTED RANGE OPENER>",
                                        opener_op_list),
        _get_state_machine_and_terminal(CloserSequence,
                                        "<SKIP NESTED RANGE OPENER>",
                                        closer_op_list)
    ]
Пример #3
0
def _get_state_machine_vs_terminal_list(CloserPattern, OpenerPattern,
                                        DoorIdExit, dial_db):
    """Additionally to all characters, the loop shall walk along the 'closer'.
    If the closer matches, the range skipping exits. Characters need to be 
    counted properly.

    RETURNS: [0] list(state machine, terminal)
             [1] incidence id of auxiliary terminal that goto-s to the
                 loop entry.

    The auxiliary terminal is necessary since the DoorID of the loop entry
    cannot be known beforehand.
    """
    # DoorID of loop entry cannot be known beforehand.
    # => generate an intermediate door_id from where the loop is entered.
    iid_aux_reentry = dial.new_incidence_id()
    door_id_aux_reentry = dial.DoorID.incidence(iid_aux_reentry, dial_db)

    # Opener Pattern Reaction
    opener_op_list = [
        Op.Increment(E_R.Counter),
        Op.GotoDoorId(door_id_aux_reentry)
    ]

    # Closer Pattern Reaction
    closer_op_list = [
        Op.Decrement(E_R.Counter),
        Op.GotoDoorIdIfCounterEqualZero(DoorIdExit),
        Op.GotoDoorId(door_id_aux_reentry)
    ]

    def sm_terminal_pair(Pattern, Name, OpList, dial_db):
        sm = Pattern.get_cloned_sm(StateMachineId=dial.new_incidence_id())
        terminal = loop.MiniTerminal(Lng.COMMAND_LIST(OpList, dial_db), Name,
                                     sm.get_id())
        return sm, terminal

    smt_list = [
        sm_terminal_pair(OpenerPattern, "<SKIP NESTED RANGE OPENER>",
                         opener_op_list, dial_db),
        sm_terminal_pair(CloserPattern, "<SKIP NESTED RANGE CLOSER>",
                         closer_op_list, dial_db)
    ]

    return smt_list, iid_aux_reentry
Пример #4
0
    def __prepare_positioning_at_loop_begin_and_exit(ColumnNPerCodeUnit):
        """With encodings of dynamic character sizes (UTF8), the pointer to the 
        first letter is stored in 'character_begin_p'. To reset the input 
        pointer 'input_p = character_begin_p' is applied.  
        """
        if Setup.buffer_encoding.variable_character_sizes_f():
            # 1 character == variable number of code units
            # => Begin of character must be stored upon entry
            #    and restored upon exit.
            entry = [Op.Assign(E_R.LoopRestartP, E_R.InputP)]
            reentry = [Op.Assign(E_R.LoopRestartP, E_R.InputP)]
            exit = [Op.Assign(E_R.InputP, E_R.LoopRestartP)]
        else:
            # 1 character == 1 code unit
            # => reset to last character: 'input_p = input_p - 1'
            entry = []
            reentry = []
            exit = [Op.Decrement(E_R.InputP)]

        if ColumnNPerCodeUnit is not None:
            entry.append(
                Op.Assign(E_R.CountReferenceP, E_R.InputP, Condition="COLUMN"))

        return entry, reentry, exit
Пример #5
0
def set_recursive_command_list(State, TheOpList):
    State.entry.enter_OpList(State.index, State.index, OpList.from_iterable(TheOpList))
    State.entry.categorize(State.index)

if "0" in sys.argv:
    analyzer, a, b = basic_setup([10, 10]) # Recursion on trigger = 10 in both states

elif "0b" in sys.argv:
    analyzer, a, b = basic_setup([10, 11]) # Recursion on trigger = 10 in a, trigger = 11 in b

elif "1" in sys.argv:
    analyzer, a, b = basic_setup([10, 10]) # Recursion on trigger = 10 in both states
    print "NOTE: Set SAME command list in recursion."
    set_recursive_command_list(a, [ Op.Increment(E_R.InputP) ])
    set_recursive_command_list(b, [ Op.Increment(E_R.InputP) ])
    
elif "1b" in sys.argv:
    analyzer, a, b = basic_setup([10, 10]) # Recursion on trigger = 10 in both states
    print "NOTE: Set DIFFERENT command list in recursion."
    set_recursive_command_list(a, [ Op.Increment(E_R.InputP) ])
    set_recursive_command_list(b, [ Op.Decrement(E_R.InputP) ])
    
elif "1c" in sys.argv:
    analyzer, a, b = basic_setup([10, 11]) # Recursion on trigger = 10 in both states
    print "NOTE: Set SAME command list in recursion ON DIFFERENT triggers."
    set_recursive_command_list(a, [ Op.Increment(E_R.InputP) ])
    set_recursive_command_list(b, [ Op.Increment(E_R.InputP) ])
    
test(analyzer, a, b)