Ejemplo n.º 1
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(
                 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_list.append(Op.InputPIncrement())
            else:                             cmd_list.append(Op.InputPDecrement())
        else:
            if self.engine_type.is_FORWARD(): cmd_list.extend([Op.InputPIncrement(), Op.InputPDereference()])
            else:                             cmd_list.extend([Op.InputPDecrement(), Op.InputPDereference()])

        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():
                ta = TransitionAction(OpList(Op.InputPDereference()))
            state.entry.enter_state_machine_entry(self.__state_machine_id, 
                                                  StateIndex, ta)

        return state
Ejemplo n.º 2
0
 def __prepare_begin_and_putback(self, OnBegin, OnEnd):
     """If we deal with variable character sizes, the begin of the letter is stored
     in 'character_begin_p'. To reset the input pointer 'input_p = character_begin_p' 
     is applied.
     """
     if not Setup.buffer_codec.variable_character_sizes_f():
         # 1 character == 1 chunk
         # => rest to last character: 'input_p = input_p - 1'
         self.on_step    = []
         self.on_putback = [ Op.InputPDecrement() ]
     else:
         # 1 character == variable number of chunks
         # => store begin of character in 'lexeme_start_p'
         # => rest to last character: 'input_p = lexeme_start_p'
         self.on_step    = [ Op.Assign(E_R.CharacterBeginP, E_R.InputP) ]
         self.on_putback = [ Op.Assign(E_R.InputP, E_R.CharacterBeginP) ]
     self.on_begin = concatinate(self.on_step, OnBegin)
     self.on_end   = concatinate(self.on_putback, OnEnd)
Ejemplo n.º 3
0
    def prepare_for_reload(self, TheAnalyzer, BeforeReloadOpList=None, 
                           AfterReloadOpList=None):
        """Prepares state for reload. Reload procedure

            .- State 'X' ---.               
            |               |                .-- Reloader------. 
            | BUFFER LIMIT  |              .----------------.  |
            | CODE detected ------->-------| Door from X:   |  |
            |               |              | Actions before |  |
            |               |              | reload.        |  |
            |               |              '----------------'  |
            |               |                |        |        |
            |               |                |  reload buffer> |
            |    .----------------.          |        |        |
            |    | Door for       |---<-------(good)--*        |
            |    | RELOAD SUCCESS:|          |        |        |
            |    | Actions after  |          |      (bad)      |
            |    | Reload.        |          '------- |--------'
            |    '----------------'                   |
            |               |                .----------------.
            '---------------'                | Door for       |
                                             | RELOAD FAILURE |
                                             '----------------'
                                   
        (1) Create 'Door for RELOAD SUCCESS'. 
        (2) Determine 'Door for RELOAD FAILURE'.
        (3) Create 'Door from X' in Reloader.
        (4) Adapt state X's transition map, so that:
              BUFFER LIMIT CODE --> reload procedure.
        """
        assert self.transition_map is not None
        assert BeforeReloadOpList is None or isinstance(BeforeReloadOpList, OpList)
        assert AfterReloadOpList  is None or isinstance(AfterReloadOpList, OpList)

        if not TheAnalyzer.engine_type.subject_to_reload():
            # Engine type does not require reload => no reload. 
            return

        elif self.transition_map.is_only_drop_out():
            # If the state drops out anyway, then there is no need to reload.
            # -- The transition map is not adapted.
            # -- The reloader is not instrumented to reload for that state.
            return                      

        assert self.index in TheAnalyzer.state_db
        reload_state = TheAnalyzer.reload_state
        assert reload_state.index in (E_StateIndices.RELOAD_FORWARD, 
                                      E_StateIndices.RELOAD_BACKWARD)

        # (1) Door for RELOAD SUCCESS
        #
        after_cl = []
        if TheAnalyzer.engine_type.is_FORWARD(): after_cl.append(Op.InputPIncrement())
        else:                                    after_cl.append(Op.InputPDecrement())
        after_cl.append(Op.InputPDereference())
        if AfterReloadOpList is not None:
            after_cl.extend(AfterReloadOpList)

        self.entry.enter_OpList(self.index, reload_state.index, OpList.from_iterable(after_cl))
        self.entry.categorize(self.index) # Categorize => DoorID is available.
        on_success_door_id = self.entry.get_door_id(self.index, reload_state.index)

        # (2) Determin Door for RELOAD FAILURE
        #
        if TheAnalyzer.is_init_state_forward(self.index):
            on_failure_door_id = DoorID.incidence(E_IncidenceIDs.END_OF_STREAM)
        else:
            on_failure_door_id = TheAnalyzer.drop_out_DoorID(self.index)

        # (3) Create 'Door from X' in Reloader
        assert on_failure_door_id != on_success_door_id
        reload_door_id = reload_state.add_state(self.index, 
                                                on_success_door_id, 
                                                on_failure_door_id, 
                                                BeforeReloadOpList)

        # (4) Adapt transition map: BUFFER LIMIT CODE --> reload_door_id
        #
        self.transition_map.set_target(Setup.buffer_limit_code, reload_door_id)
        return
Ejemplo n.º 4
0
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.InputPIncrement()])
    set_recursive_command_list(b, [Op.InputPIncrement()])

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.InputPIncrement()])
    set_recursive_command_list(b, [Op.InputPDecrement()])

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.InputPIncrement()])
    set_recursive_command_list(b, [Op.InputPIncrement()])

test(analyzer, a, b)