Esempio n. 1
0
    def __init__(self, StateIndex, DoorId_OpList):
        self.state_index = StateIndex
        root_child_set   = set(door_id for door_id, cl in DoorId_OpList) 
        self.root        = Door(dial_db.new_door_id(StateIndex), [], None,
                                root_child_set)
        self.door_db     = TypedDict(DoorID, Door) # {}   # map: DoorID --> Door 
        #                       #  ... with ALL Door-s related to the 'problem'

        # map: Shared Tail --> SharedTailCandidateSet
        self._tail_db      = {} # map: command list tail --> those who share it
        self._candidate_db = {} # map: DoorID --> Door 
        #                       #  ... but only with those DoorID-s that are 
        #                       #      subject to shared tail investigation.

        # Doors which cannot extract a tail are dropped from consideration. 
        # (See discussion at end [DROP_NON_SHARER])
        # BUT: First the WHOLE SET of Door-s must be considered! 
        # If a Door shares from the beginning => into 'good_set'.
        # Else, look into _tail_db if it finally shared something. 
        good_set = set()

        for door_id, command_list in DoorId_OpList:
            door = Door(door_id, command_list, self.root, set())
            if self._tail_db_enter(door_id, door): 
                good_set.add(door_id)
            self._candidate_db[door_id] = door
            self.door_db[door_id]       = door

        # Drop non-sharing Door-s. 
        # (See [DROP_NON_SHARER])
        for door_id in self._candidate_db.keys():
            if   door_id in good_set:                continue
            elif self._tail_db_has_door_id(door_id): continue
            del self._candidate_db[door_id]
Esempio n. 2
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
Esempio n. 3
0
    def __init__(self, StateIndex, DoorId_OpList):
        self.state_index = StateIndex
        root_child_set = set(door_id for door_id, cl in DoorId_OpList)
        self.root = Door(dial_db.new_door_id(StateIndex), [], None,
                         root_child_set)
        self.door_db = TypedDict(DoorID, Door)  # {}   # map: DoorID --> Door
        #                       #  ... with ALL Door-s related to the 'problem'

        # map: Shared Tail --> SharedTailCandidateSet
        self._tail_db = {}  # map: command list tail --> those who share it
        self._candidate_db = {}  # map: DoorID --> Door
        #                       #  ... but only with those DoorID-s that are
        #                       #      subject to shared tail investigation.

        # Doors which cannot extract a tail are dropped from consideration.
        # (See discussion at end [DROP_NON_SHARER])
        # BUT: First the WHOLE SET of Door-s must be considered!
        # If a Door shares from the beginning => into 'good_set'.
        # Else, look into _tail_db if it finally shared something.
        good_set = set()

        for door_id, command_list in DoorId_OpList:
            door = Door(door_id, command_list, self.root, set())
            if self._tail_db_enter(door_id, door):
                good_set.add(door_id)
            self._candidate_db[door_id] = door
            self.door_db[door_id] = door

        # Drop non-sharing Door-s.
        # (See [DROP_NON_SHARER])
        for door_id in self._candidate_db.keys():
            if door_id in good_set: continue
            elif self._tail_db_has_door_id(door_id): continue
            del self._candidate_db[door_id]
Esempio n. 4
0
        def _get_door_id(CL):
            # If there was an action with the same command list, then assign
            # the same door id. Leave the action intact! May be, it is modified
            # later and will differ from the currently same action.
            new_door_id = command_list_db.get(CL)

            if new_door_id is not None: return new_door_id

            return dial_db.new_door_id(StateIndex)
Esempio n. 5
0
        def _get_door_id(CL):
            # If there was an action with the same command list, then assign
            # the same door id. Leave the action intact! May be, it is modified
            # later and will differ from the currently same action.
            new_door_id = command_list_db.get(CL)

            if new_door_id is not None: return new_door_id

            return dial_db.new_door_id(StateIndex)
Esempio n. 6
0
def get(CCFactory, Name):
    """Implement the default counter for a given Counter Database. 

    In case the line and column number increment cannot be determined before-
    hand, a something must be there that can count according to the rules given
    in 'CCFactory'. This function generates the code for a general counter
    function which counts line and column number increments starting from the
    begin of a lexeme to its end.

    The implementation of the default counter is a direct function of the
    'CCFactory', i.e. the database telling how characters influence the
    line and column number counting. 
    
    Multiple modes may have the same character counting behavior. If so, 
    then there's only one counter implemented while others refer to it. 

    ---------------------------------------------------------------------------
    
    RETURNS: function_name, string --> Function name and the implementation 
                                       of the character counter.
             function_name, None   --> The 'None' implementation indicates that
                                       NO NEW counter is implemented. An 
                                       appropriate counter can be accessed 
                                       by the 'function name'.
    ---------------------------------------------------------------------------
    """
    function_name = DefaultCounterFunctionDB.get_function_name(CCFactory)
    if function_name is not None:
        return function_name, None # Implementation has been done before.

    function_name  = Lng.DEFAULT_COUNTER_FUNCTION_NAME(Name) 

    door_id_return = dial_db.new_door_id()
    code,          \
    door_id_beyond = loop.do(CCFactory, 
                             AfterBeyond     = [ GotoDoorId(door_id_return) ],
                             LexemeEndCheckF = True,
                             EngineType      = engine.CHARACTER_COUNTER)

    implementation = __frame(function_name, Lng.INPUT_P(), code, door_id_return, 
                             door_id_beyond) 

    DefaultCounterFunctionDB.enter(CCFactory, function_name)

    return function_name, implementation
Esempio n. 7
0
def get(CCFactory, Name):
    """Implement the default counter for a given Counter Database. 

    In case the line and column number increment cannot be determined before-
    hand, a something must be there that can count according to the rules given
    in 'CCFactory'. This function generates the code for a general counter
    function which counts line and column number increments starting from the
    begin of a lexeme to its end.

    The implementation of the default counter is a direct function of the
    'CCFactory', i.e. the database telling how characters influence the
    line and column number counting. 
    
    Multiple modes may have the same character counting behavior. If so, 
    then there's only one counter implemented while others refer to it. 

    ---------------------------------------------------------------------------
    
    RETURNS: function_name, string --> Function name and the implementation 
                                       of the character counter.
             function_name, None   --> The 'None' implementation indicates that
                                       NO NEW counter is implemented. An 
                                       appropriate counter can be accessed 
                                       by the 'function name'.
    ---------------------------------------------------------------------------
    """
    function_name = DefaultCounterFunctionDB.get_function_name(CCFactory)
    if function_name is not None:
        return function_name, None # Implementation has been done before.

    function_name  = Lng.DEFAULT_COUNTER_FUNCTION_NAME(Name) 

    door_id_return = dial_db.new_door_id()
    code,          \
    door_id_beyond = loop.do(CCFactory, 
                             OnLoopExit      = [ Op.GotoDoorId(door_id_return) ],
                             LexemeEndCheckF = True,
                             EngineType      = engine.CHARACTER_COUNTER)

    implementation = __frame(function_name, Lng.INPUT_P(), code, door_id_return, 
                             door_id_beyond) 

    DefaultCounterFunctionDB.enter(CCFactory, function_name)

    return function_name, implementation
Esempio n. 8
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
Esempio n. 9
0
def get_skipper(OpenerSequence, CloserSequence, CloserPattern, ModeName,
                OnSkipRangeOpen, DoorIdAfter):
    assert len(OpenerSequence) >= 1
    assert len(CloserSequence) >= 1
    assert OpenerSequence != CloserSequence

    skipper_index = sm_index.get()
    skipper_door_id = dial_db.new_door_id(skipper_index)

    opener_str, opener_comment_str = get_character_sequence(OpenerSequence)
    opener_length = len(OpenerSequence)
    closer_str, closer_comment_str = get_character_sequence(CloserSequence)
    closer_length = len(CloserSequence)

    variable_db.require("reference_p",
                        Condition="QUEX_OPTION_COLUMN_NUMBER_COUNTING")
    variable_db.require("counter")
    variable_db.require_array("Skipper%i_Opener",
                              Initial="{ %s }" % opener_str,
                              ElementN=opener_length,
                              Index=skipper_index)
    variable_db.require("Skipper%i_OpenerEnd",
                        "Skipper%i_Opener + (ptrdiff_t)%i" %
                        (skipper_index, opener_length),
                        Index=skipper_index)
    variable_db.require("Skipper%i_Opener_it", "0x0", Index=skipper_index)
    variable_db.require_array("Skipper%i_Closer",
                              Initial="{ %s }" % closer_str,
                              ElementN=closer_length,
                              Index=skipper_index)
    variable_db.require("Skipper%i_CloserEnd",
                        "Skipper%i_Closer + (ptrdiff_t)%i" %
                        (skipper_index, closer_length),
                        Index=skipper_index)
    variable_db.require("Skipper%i_Closer_it", "0x0", Index=skipper_index)

    reference_p_def = "    __QUEX_IF_COUNT_COLUMNS(reference_p = QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer));\n"
    before_reload   = "    __QUEX_IF_COUNT_COLUMNS_ADD((size_t)(QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer)\n" + \
                      "                                - reference_p));\n"
    after_reload = "        __QUEX_IF_COUNT_COLUMNS(reference_p = QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer));\n"

    if CloserSequence[-1] == ord('\n'):
        end_procedure = "       __QUEX_IF_COUNT_LINES_ADD((size_t)1);\n"
        end_procedure += "       __QUEX_IF_COUNT_COLUMNS_SET((size_t)1);\n"
    else:
        end_procedure = "        __QUEX_IF_COUNT_COLUMNS_ADD((size_t)(QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer)\n" + \
                        "                                    - reference_p));\n"

    reload_door_id = dial_db.new_door_id()
    on_skip_range_open = get_on_skip_range_open(OnSkipRangeOpen,
                                                CloserPattern,
                                                NestedF=True)

    code_str = blue_print(
        template_str,
        [
            ["$$SKIPPER_INDEX$$", __nice(skipper_index)],
            #
            ["$$OPENER_LENGTH$$", "%i" % opener_length],
            ["$$INPUT_P_INCREMENT$$",
             Lng.INPUT_P_INCREMENT()],
            ["$$INPUT_P_DECREMENT$$",
             Lng.INPUT_P_DECREMENT()],
            ["$$INPUT_GET$$", Lng.ACCESS_INPUT()],
            [
                "$$IF_INPUT_EQUAL_DELIMITER_0$$",
                Lng.IF_INPUT("==", "Skipper$$SKIPPER_INDEX$$[0]")
            ],
            ["$$ENDIF$$", Lng.END_IF()],
            ["$$ENTRY$$", Lng.LABEL(skipper_door_id)],
            ["$$RELOAD$$",
             dial_db.get_label_by_door_id(reload_door_id)],
            ["$$GOTO_AFTER_END_OF_SKIPPING$$",
             Lng.GOTO(DoorIdAfter)],
            ["$$GOTO_RELOAD$$", Lng.GOTO(reload_door_id)],
            ["$$INPUT_P_TO_LEXEME_START$$",
             Lng.INPUT_P_TO_LEXEME_START()],
            # When things were skipped, no change to acceptance flags or modes has
            # happend. One can jump immediately to the start without re-entry preparation.
            ["$$GOTO_ENTRY$$", Lng.GOTO(skipper_door_id)],
            ["$$MARK_LEXEME_START$$",
             Lng.LEXEME_START_SET()],
            ["$$ON_SKIP_RANGE_OPEN$$", on_skip_range_open],
            #
            ["$$LC_COUNT_COLUMN_N_POINTER_DEFINITION$$", reference_p_def],
            ["$$LC_COUNT_IN_LOOP$$",
             line_column_counter_in_loop()],
            ["$$LC_COUNT_END_PROCEDURE$$", end_procedure],
            ["$$LC_COUNT_BEFORE_RELOAD$$", before_reload],
            ["$$LC_COUNT_AFTER_RELOAD$$", after_reload],
        ])

    return [code_str]
Esempio n. 10
0
    def _setup_new_node(self, Candidate):
        """A Tail has been identified as being shared and is now to be extracted
        from the sharing doors. Example: 'Y, Z' is a shared tail of doord 1 and 2:
        
                        Door 1:  [ X, Y, Z ] ---------.
                                                      |
                        Door 2:  [ U, V, Y, Z ] ------+
                        ...                            +----> root
                        Door N:  [ P, Q, Z ] ---------'

        The 'Y, Z' is extracted into a new door, and door 1 and 2 need to goto the
        new door after the end of their pruned tail.

                        Door 1:  [ X ] --------.  new Door 
                                               |
                        Door 2:  [ U, V ] -----+--[ Y, Z ]--.
                        ...                                  +----> root
                        Door N:  [ P, Q, Z ] ---------------'

        PROCEDURE: (1) Generate DoorID for the new node.
                   (2) Prune the command lists of the sharing doors.
                   (3) Set their 'parent' to the new node's DoorID.
                   (4) Enter new node with (DoorID, Tail) into the door database.

        RESULT: The new Door

            .command_list = the shared tail
            .child_set    = all sharing doors (Door 0, Door 1, ...)
            .parent       = root (which is ALWAYS the parent of nodes subject 
                            to investigation).
        """
        new_door_id = dial_db.new_door_id(self.state_index)
        child_set = set(Candidate.door_id_iterable())
        new_door = Door(new_door_id, list(Candidate.shared_tail), self.root,
                        child_set)

        self.door_db[new_door_id] = new_door

        for door_id, cut_index_list in Candidate.cut_db.items(
        ):  # NOT: 'iteritems()'
            door = self._candidate_db[door_id]
            # The cut_index_list MUST be sorted in a way, that last index comes
            # first. Otherwise, the 'del' operator cannot be applied conveniently.
            last_i = None
            for i in cut_index_list:
                assert last_i is None or i < last_i
                del door.command_list[i]
                last_i = i

            # Doors that have been combined, did so with the 'longest' possible
            # tail. Thus, they are done!
            self._remove(door_id)
            # -- '.parent' is only set to new doors.
            # -- all new doors relate to '.root'.
            # => The parent of all considered Door-s in the database is '.root'
            assert door.parent == self.root
            door.parent = new_door
            self.root.child_set.remove(door_id)

        self.root.child_set.add(new_door_id)

        if self._tail_db_enter(new_door_id, new_door):
            # A new Door that does not share anything does not have to be
            # considered. See discussion at end of file [DROP_NON_SHARER].
            self._candidate_db[new_door_id] = new_door
Esempio n. 11
0
def get_skipper(EndSequence, CloserPattern, ModeName, OnSkipRangeOpen,
                DoorIdAfter):
    assert len(EndSequence) >= 1

    global template_str

    # Name the $$SKIPPER$$
    skipper_index = sm_index.get()
    skipper_door_id = dial_db.new_door_id(skipper_index)

    delimiter_str, delimiter_comment_str = get_character_sequence(EndSequence)

    end_sequence_transformed = transformation.do_sequence(EndSequence)

    # Determine the $$DELIMITER$$
    delimiter_length = len(end_sequence_transformed)

    delimiter_comment_str = Lng.COMMENT(
        "                         Delimiter: %s" % delimiter_comment_str)

    # Determine the check for the tail of the delimiter
    delimiter_remainder_test_str = ""
    if len(EndSequence) != 1:
        txt = "".join("    %s" %
                      Lng.IF_GOTO(Lng.INPUT_P_DEREFERENCE(
                          i - 1), "!=", "Skipper$$SKIPPER_INDEX$$[%i]" %
                                  i, skipper_door_id, i == 1)
                      for i, letter in enumerate(EndSequence[1:], start=1))
        delimiter_remainder_test_str = txt

    door_id_reload = dial_db.new_door_id()
    on_skip_range_open = get_on_skip_range_open(OnSkipRangeOpen, CloserPattern)

    # The main part
    code_str = blue_print(
        template_str,
        [
            ["$$DELIMITER_COMMENT$$", delimiter_comment_str],
            ["$$INPUT_P_INCREMENT$$",
             Lng.INPUT_P_INCREMENT()],
            ["$$INPUT_P_DECREMENT$$",
             Lng.INPUT_P_DECREMENT()],
            ["$$INPUT_GET$$", Lng.ACCESS_INPUT()],
            [
                "$$IF_INPUT_EQUAL_DELIMITER_0$$",
                Lng.IF_INPUT("==", "Skipper$$SKIPPER_INDEX$$[0]")
            ],
            ["$$ENDIF$$", Lng.END_IF()],
            ["$$ENTRY$$",
             dial_db.get_label_by_door_id(skipper_door_id)],
            ["$$RELOAD$$",
             dial_db.get_label_by_door_id(door_id_reload)],
            ["$$GOTO_ENTRY$$", Lng.GOTO(skipper_door_id)],
            ["$$INPUT_P_TO_LEXEME_START$$",
             Lng.INPUT_P_TO_LEXEME_START()],
            # When things were skipped, no change to acceptance flags or modes has
            # happend. One can jump immediately to the start without re-entry preparation.
            ["$$GOTO_AFTER_END_OF_SKIPPING$$",
             Lng.GOTO(DoorIdAfter)],
            ["$$MARK_LEXEME_START$$",
             Lng.LEXEME_START_SET()],
            ["$$DELIMITER_REMAINDER_TEST$$", delimiter_remainder_test_str],
            ["$$ON_SKIP_RANGE_OPEN$$", on_skip_range_open],
        ])

    # Line and column number counting
    code_str, reference_p_f = __lc_counting_replacements(code_str, EndSequence)

    # The finishing touch
    code_str = blue_print(
        code_str,
        [["$$SKIPPER_INDEX$$", __nice(skipper_index)],
         ["$$GOTO_RELOAD$$", Lng.GOTO(door_id_reload)]])

    if reference_p_f:
        variable_db.require("reference_p",
                            Condition="QUEX_OPTION_COLUMN_NUMBER_COUNTING")

    variable_db.require_array("Skipper%i",
                              Initial="{ %s }" % delimiter_str,
                              ElementN=delimiter_length,
                              Index=skipper_index)
    variable_db.require("Skipper%iL",
                        "%i" % delimiter_length,
                        Index=skipper_index)
    variable_db.require("text_end")

    variable_db.require("input")

    return [code_str]
Esempio n. 12
0
    def _setup_new_node(self, Candidate):
        """A Tail has been identified as being shared and is now to be extracted
        from the sharing doors. Example: 'Y, Z' is a shared tail of doord 1 and 2:
        
                        Door 1:  [ X, Y, Z ] ---------.
                                                      |
                        Door 2:  [ U, V, Y, Z ] ------+
                        ...                            +----> root
                        Door N:  [ P, Q, Z ] ---------'

        The 'Y, Z' is extracted into a new door, and door 1 and 2 need to goto the
        new door after the end of their pruned tail.

                        Door 1:  [ X ] --------.  new Door 
                                               |
                        Door 2:  [ U, V ] -----+--[ Y, Z ]--.
                        ...                                  +----> root
                        Door N:  [ P, Q, Z ] ---------------'

        PROCEDURE: (1) Generate DoorID for the new node.
                   (2) Prune the command lists of the sharing doors.
                   (3) Set their 'parent' to the new node's DoorID.
                   (4) Enter new node with (DoorID, Tail) into the door database.

        RESULT: The new Door

            .command_list = the shared tail
            .child_set    = all sharing doors (Door 0, Door 1, ...)
            .parent       = root (which is ALWAYS the parent of nodes subject 
                            to investigation).
        """
        new_door_id = dial_db.new_door_id(self.state_index)
        child_set   = set(Candidate.door_id_iterable())
        new_door    = Door(new_door_id, list(Candidate.shared_tail), self.root, child_set)

        self.door_db[new_door_id] = new_door

        for door_id, cut_index_list in Candidate.cut_db.items(): # NOT: 'iteritems()'
            door = self._candidate_db[door_id]
            # The cut_index_list MUST be sorted in a way, that last index comes
            # first. Otherwise, the 'del' operator cannot be applied conveniently. 
            last_i = None
            for i in cut_index_list:
                assert last_i is None or i < last_i
                del door.command_list[i]
                last_i = i

            # Doors that have been combined, did so with the 'longest' possible
            # tail. Thus, they are done!
            self._remove(door_id)
            # -- '.parent' is only set to new doors.
            # -- all new doors relate to '.root'.
            # => The parent of all considered Door-s in the database is '.root'
            assert door.parent == self.root
            door.parent = new_door
            self.root.child_set.remove(door_id)

        self.root.child_set.add(new_door_id)

        if self._tail_db_enter(new_door_id, new_door):
            # A new Door that does not share anything does not have to be 
            # considered. See discussion at end of file [DROP_NON_SHARER].
            self._candidate_db[new_door_id] = new_door
Esempio n. 13
0
def get_skipper(OpenerSequence, CloserSequence, CloserPattern, ModeName, OnSkipRangeOpen, DoorIdAfter):
    assert len(OpenerSequence) >= 1
    assert len(CloserSequence) >= 1
    assert OpenerSequence != CloserSequence

    skipper_index   = sm_index.get()
    skipper_door_id = dial_db.new_door_id(skipper_index)

    opener_str, opener_comment_str = get_character_sequence(OpenerSequence)
    opener_length = len(OpenerSequence)
    closer_str, closer_comment_str = get_character_sequence(CloserSequence)
    closer_length = len(CloserSequence)

    variable_db.require("reference_p", Condition="QUEX_OPTION_COLUMN_NUMBER_COUNTING")
    variable_db.require("counter")
    variable_db.require_array("Skipper%i_Opener", Initial="{ %s }" % opener_str, ElementN=opener_length, Index = skipper_index)
    variable_db.require("Skipper%i_OpenerEnd", "Skipper%i_Opener + (ptrdiff_t)%i" % (skipper_index, opener_length), Index = skipper_index) 
    variable_db.require("Skipper%i_Opener_it", "0x0", Index = skipper_index) 
    variable_db.require_array("Skipper%i_Closer", Initial="{ %s }" % closer_str, ElementN=closer_length, Index = skipper_index) 
    variable_db.require("Skipper%i_CloserEnd", "Skipper%i_Closer + (ptrdiff_t)%i" % (skipper_index, closer_length), Index = skipper_index) 
    variable_db.require("Skipper%i_Closer_it", "0x0", Index = skipper_index) 

    reference_p_def = "    __QUEX_IF_COUNT_COLUMNS(reference_p = QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer));\n"
    before_reload   = "    __QUEX_IF_COUNT_COLUMNS_ADD((size_t)(QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer)\n" + \
                      "                                - reference_p));\n" 
    after_reload    = "        __QUEX_IF_COUNT_COLUMNS(reference_p = QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer));\n"

    if CloserSequence[-1] == ord('\n'):
        end_procedure  = "       __QUEX_IF_COUNT_LINES_ADD((size_t)1);\n"
        end_procedure += "       __QUEX_IF_COUNT_COLUMNS_SET((size_t)1);\n"
    else:
        end_procedure = "        __QUEX_IF_COUNT_COLUMNS_ADD((size_t)(QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer)\n" + \
                        "                                    - reference_p));\n" 

    reload_door_id     = dial_db.new_door_id()
    on_skip_range_open = get_on_skip_range_open(OnSkipRangeOpen, CloserPattern, NestedF=True)

    code_str = blue_print(template_str, [
                   ["$$SKIPPER_INDEX$$",   __nice(skipper_index)],
                   #
                   ["$$OPENER_LENGTH$$",                  "%i" % opener_length],
                   ["$$INPUT_P_INCREMENT$$",              Lng.INPUT_P_INCREMENT()],
                   ["$$INPUT_P_DECREMENT$$",              Lng.INPUT_P_DECREMENT()],
                   ["$$INPUT_GET$$",                      Lng.ACCESS_INPUT()],
                   ["$$IF_INPUT_EQUAL_DELIMITER_0$$",     Lng.IF_INPUT("==", "Skipper$$SKIPPER_INDEX$$[0]")],
                   ["$$ENDIF$$",                          Lng.END_IF()],
                   ["$$ENTRY$$",                          Lng.LABEL(skipper_door_id)],
                   ["$$RELOAD$$",                         dial_db.get_label_by_door_id(reload_door_id)],
                   ["$$GOTO_AFTER_END_OF_SKIPPING$$",     Lng.GOTO(DoorIdAfter)], 
                   ["$$GOTO_RELOAD$$",                    Lng.GOTO(reload_door_id)],
                   ["$$INPUT_P_TO_LEXEME_START$$",        Lng.INPUT_P_TO_LEXEME_START()],
                   # When things were skipped, no change to acceptance flags or modes has
                   # happend. One can jump immediately to the start without re-entry preparation.
                   ["$$GOTO_ENTRY$$",                     Lng.GOTO(skipper_door_id)],
                   ["$$MARK_LEXEME_START$$",              Lng.LEXEME_START_SET()],
                   ["$$ON_SKIP_RANGE_OPEN$$",             on_skip_range_open],
                   #
                   ["$$LC_COUNT_COLUMN_N_POINTER_DEFINITION$$", reference_p_def],
                   ["$$LC_COUNT_IN_LOOP$$",                     line_column_counter_in_loop()],
                   ["$$LC_COUNT_END_PROCEDURE$$",               end_procedure],
                   ["$$LC_COUNT_BEFORE_RELOAD$$",               before_reload],
                   ["$$LC_COUNT_AFTER_RELOAD$$",                after_reload],
               ])

    return [ code_str ]
Esempio n. 14
0
def get_skipper(EndSequence, CloserPattern, ModeName, OnSkipRangeOpen, DoorIdAfter):
    assert len(EndSequence) >= 1

    global template_str

    # Name the $$SKIPPER$$
    skipper_index   = sm_index.get()
    skipper_door_id = dial_db.new_door_id(skipper_index)

    delimiter_str, delimiter_comment_str = get_character_sequence(EndSequence)

    end_sequence_transformed = transformation.do_sequence(EndSequence)

    # Determine the $$DELIMITER$$
    delimiter_length = len(end_sequence_transformed)

    delimiter_comment_str = Lng.COMMENT("                         Delimiter: %s" % delimiter_comment_str)

    # Determine the check for the tail of the delimiter
    delimiter_remainder_test_str = ""
    if len(EndSequence) != 1: 
        txt = "".join(
            "    %s" % Lng.IF_GOTO(Lng.INPUT_P_DEREFERENCE(i-1), "!=", 
                                   "Skipper$$SKIPPER_INDEX$$[%i]" % i,
                                   skipper_door_id, i == 1)
            for i, letter in enumerate(EndSequence[1:], start=1)
        )
        delimiter_remainder_test_str = txt

    door_id_reload = dial_db.new_door_id()
    on_skip_range_open = get_on_skip_range_open(OnSkipRangeOpen, CloserPattern)

    # The main part
    code_str = blue_print(template_str,
                          [
                           ["$$DELIMITER_COMMENT$$",              delimiter_comment_str],
                           ["$$INPUT_P_INCREMENT$$",              Lng.INPUT_P_INCREMENT()],
                           ["$$INPUT_P_DECREMENT$$",              Lng.INPUT_P_DECREMENT()],
                           ["$$INPUT_GET$$",                      Lng.ACCESS_INPUT()],
                           ["$$IF_INPUT_EQUAL_DELIMITER_0$$",     Lng.IF_INPUT("==", "Skipper$$SKIPPER_INDEX$$[0]")],
                           ["$$ENDIF$$",                          Lng.END_IF()],
                           ["$$ENTRY$$",                          dial_db.get_label_by_door_id(skipper_door_id)],
                           ["$$RELOAD$$",                         dial_db.get_label_by_door_id(door_id_reload)],
                           ["$$GOTO_ENTRY$$",                     Lng.GOTO(skipper_door_id)],
                           ["$$INPUT_P_TO_LEXEME_START$$",        Lng.INPUT_P_TO_LEXEME_START()],
                           # When things were skipped, no change to acceptance flags or modes has
                           # happend. One can jump immediately to the start without re-entry preparation.
                           ["$$GOTO_AFTER_END_OF_SKIPPING$$",     Lng.GOTO(DoorIdAfter)], 
                           ["$$MARK_LEXEME_START$$",              Lng.LEXEME_START_SET()],
                           ["$$DELIMITER_REMAINDER_TEST$$",       delimiter_remainder_test_str],
                           ["$$ON_SKIP_RANGE_OPEN$$",             on_skip_range_open],
                          ])

    # Line and column number counting
    code_str, reference_p_f = __lc_counting_replacements(code_str, EndSequence)

    # The finishing touch
    code_str = blue_print(code_str,
                          [["$$SKIPPER_INDEX$$", __nice(skipper_index)],
                           ["$$GOTO_RELOAD$$",   Lng.GOTO(door_id_reload)]])

    if reference_p_f:
        variable_db.require("reference_p", Condition="QUEX_OPTION_COLUMN_NUMBER_COUNTING")

    variable_db.require_array("Skipper%i", Initial="{ %s }" % delimiter_str, ElementN=delimiter_length, Index=skipper_index)
    variable_db.require("Skipper%iL", "%i" % delimiter_length, Index=skipper_index)
    variable_db.require("text_end")

    variable_db.require("input") 

    return [ code_str ]