Example #1
0
    def do(self, RequiredLocalVariablesDB):
        LanguageDB = Setup.language_db

        # (*) Initialize the label and variable trackers
        variable_db.init(RequiredLocalVariablesDB)
        variable_db.require("input") 

        init_address_handling({})

        # (*) Pre Context State Machine
        #     (If present: All pre-context combined in single backward analyzer.)
        pre_context = self.__code_pre_context_state_machine()
            
        # (*) Main State Machine -- try to match core patterns
        main        = self.__code_main_state_machine()

        # (*) Backward input position detection
        #     (Seldomly present -- only for Pseudo-Ambiguous Post Contexts)
        bipd        = self.__code_backward_input_position_detection()

        # (*) Determine required labels and variables
        routed_address_set = get_address_set_subject_to_routing()
        routed_address_set.add(get_address("$terminal-EOF", U=True))
        routed_state_info_list = state_router_generator.get_info(routed_address_set)
        state_router           = [ state_router_generator.do(routed_state_info_list) ]

        variable_db.require("target_state_index", Condition_ComputedGoto=False) 

        if is_label_referenced("$reload-FORWARD") or is_label_referenced("$reload-BACKWARD"):
            variable_db.require("target_state_else_index")
            variable_db.require("target_state_index")

        # Following function refers to the global 'variable_db'
        variable_definitions = self.language_db.VARIABLE_DEFINITIONS(variable_db)

        function_body = []
        function_body.extend(pre_context)  # implementation of pre-contexts (if there are some)
        function_body.extend(main)         # main pattern matcher
        function_body.extend(bipd)         # (seldom != empty; only for pseudo-ambiguous post contexts)
        function_body.extend(state_router) # route to state by index (only if no computed gotos)

        # (*) Pack Pre-Context and Core State Machine into a single function
        analyzer_function = self.language_db["$analyzer-func"](self.state_machine_name, 
                                                               Setup,
                                                               variable_definitions, 
                                                               function_body, 
                                                               self.mode_name_list) 

        txt  = [ LanguageDB["$header-definitions"](LanguageDB, self.on_after_match) ]
        txt += get_plain_strings(analyzer_function)
        for i, element in enumerate(txt):
            if not isinstance(element, (str, unicode)):
                print element.__class__.__name__
                for k in range(max(0,i-10)):
                    print "before:", k, txt[k]
                for k in range(i+1, min(i+10, len(txt))):
                    print "after: ", k, txt[k]
                assert False
        return txt
Example #2
0
 def GOTO_TERMINAL(self, AcceptanceID):
     if AcceptanceID == E_AcceptanceIDs.VOID: 
         return "QUEX_GOTO_TERMINAL(last_acceptance);"
     elif AcceptanceID == E_AcceptanceIDs.FAILURE:
         return "goto _%i; /* TERMINAL_FAILURE */" % get_address("$terminal-FAILURE")
     else:
         assert isinstance(AcceptanceID, (int, long))
         return "goto TERMINAL_%i;" % AcceptanceID
Example #3
0
 def address(Target, StateKey, TheState):
     if Target == E_StateIndices.DROP_OUT:
         # All drop outs end up at the end of the transition map, where
         # it is routed via the state_key to the state's particular drop out.
         return get_address("$drop-out", TState.index, U=True, R=True)
     else:
         from_state_index = TheState.map_state_key_to_state_index(StateKey)
         door_id = StateDB[Target].entry.get_door_id(Target, FromStateIndex=from_state_index)
         return LanguageDB.ADDRESS_BY_DOOR_ID(door_id)
Example #4
0
    def GOTO_RELOAD(self, StateIndex, InitStateIndexF, EngineType):
        """On reload a special section is entered that tries to reload data. Reload
           has two possible results:
           
           -- Data has been loaded: Now, a new input character can be determined
              and the current transition map can be reentered. For convenience, 
              'RELOAD' expects to jump to right before the place where the input
              pointer is adapted.

           -- No data available to be loaded: Then the current state's drop-out
              section must be entered. The forward init state immediate jumps
              to 'end of stream'.

           Thus: The reload behavior can be determined based on **one** state index.
                 The related drop-out label can be determined here.
        """
        direction = {
            E_EngineTypes.FORWARD: "FORWARD",
            E_EngineTypes.BACKWARD_PRE_CONTEXT: "BACKWARD",
            E_EngineTypes.BACKWARD_INPUT_POSITION: None,
            E_EngineTypes.INDENTATION_COUNTER: "FORWARD",
            # There is never a reload on backward input position detection.
            # The lexeme to parse must lie inside the borders!
        }[EngineType]
        assert direction is not None, \
               "There is no reload during BACKWARD_INPUT_POSITION detection."

        # 'DoorIndex == 0' is the entry into the state without any actions.
        on_success = get_address("$entry",
                                 entry_action.DoorID(StateIndex, DoorIndex=0),
                                 U=True)
        if InitStateIndexF and EngineType == E_EngineTypes.FORWARD:
            on_fail = get_address("$terminal-EOF", U=True)
        else:
            on_fail = get_address("$drop-out", StateIndex, U=True, R=True)

        get_label("$state-router", U=True)  # Mark as 'referenced'
        get_label("$reload-%s" % direction, U=True)  # ...
        return "QUEX_GOTO_RELOAD_%s(%s, %s);" % (direction, on_success,
                                                 on_fail)
Example #5
0
    def GOTO_RELOAD(self, StateIndex, InitStateIndexF, EngineType):
        """On reload a special section is entered that tries to reload data. Reload
           has two possible results:
           
           -- Data has been loaded: Now, a new input character can be determined
              and the current transition map can be reentered. For convenience, 
              'RELOAD' expects to jump to right before the place where the input
              pointer is adapted.

           -- No data available to be loaded: Then the current state's drop-out
              section must be entered. The forward init state immediate jumps
              to 'end of stream'.

           Thus: The reload behavior can be determined based on **one** state index.
                 The related drop-out label can be determined here.
        """
        direction = { 
            E_EngineTypes.FORWARD:              "FORWARD",
            E_EngineTypes.BACKWARD_PRE_CONTEXT: "BACKWARD",
            E_EngineTypes.BACKWARD_INPUT_POSITION: None,
            E_EngineTypes.INDENTATION_COUNTER:  "FORWARD",
            # There is never a reload on backward input position detection.
            # The lexeme to parse must lie inside the borders!
        }[EngineType]
        assert direction is not None, \
               "There is no reload during BACKWARD_INPUT_POSITION detection."

        # 'DoorIndex == 0' is the entry into the state without any actions.
        on_success = get_address("$entry", entry_action.DoorID(StateIndex, DoorIndex=0), U=True)
        if InitStateIndexF and EngineType == E_EngineTypes.FORWARD:
            on_fail = get_address("$terminal-EOF", U=True) 
        else:
            on_fail = get_address("$drop-out", StateIndex, U=True, R=True) 

        get_label("$state-router", U=True)            # Mark as 'referenced'
        get_label("$reload-%s" % direction, U=True)   # ...
        return "QUEX_GOTO_RELOAD_%s(%s, %s);" % (direction, on_success, on_fail)
Example #6
0
def get_info(StateIndexList):
    # In some strange cases, a 'dummy' state router is required so that
    # 'goto __STATE_ROUTER;' does not reference a non-existing label. Then,
    # we return an empty text array.
    if len(StateIndexList) == 0: return []

    # Make sure, that for every state the 'drop-out' state is also mentioned
    result = [None] * len(StateIndexList)
    for i, index in enumerate(StateIndexList):
        assert type(index) != str
        if index >= 0:
            # Transition to state entry
            code = "goto %s; " % get_label_of_address(index)
            result[i] = (index, code)
        else:
            # Transition to a templates 'drop-out'
            code = "goto " + get_label("$drop-out", -index) + "; "
            result[i] = (get_address("$drop-out", -index), code)
    return result
Example #7
0
def get_info(StateIndexList):
    # In some strange cases, a 'dummy' state router is required so that 
    # 'goto __STATE_ROUTER;' does not reference a non-existing label. Then,
    # we return an empty text array.
    if len(StateIndexList) == 0: return []

    # Make sure, that for every state the 'drop-out' state is also mentioned
    result = [None] * len(StateIndexList)
    for i, index in enumerate(StateIndexList):
        assert type(index) != str
        if index >= 0:
            # Transition to state entry
            code = "goto %s; " % get_label_of_address(index)
            result[i] = (index, code)
        else:
            # Transition to a templates 'drop-out'
            code = "goto " + get_label("$drop-out", - index) + "; "
            result[i] = (get_address("$drop-out", - index), code)
    return result
Example #8
0
    def address(Target, StateKey, TheState):
        if Target == E_StateIndices.DROP_OUT:
            # All drop outs end up at the end of the transition map, where
            # it is routed via the state_key to the state's particular drop out.
            return get_address("$drop-out", TState.index, U=True, R=True)

        from_state_index = TheState.map_state_key_to_state_index(StateKey)
        door_id = StateDB[Target].entry.get_door_id(Target, FromStateIndex=from_state_index)

        if door_id is None:
            # IMPORTANT NOTE: (This case is separated to make this comment)
            #
            # A MegaState's transition map may be partly covered by the
            # MegaState's head.  This implies, that not all implemented
            # states trigger to the state mentioned in the transition map.
            # (A 'pseudo-common' .target_state_index may be split into a
            # scheme, because the entering doors differ.) As a result the
            # '.get_door_id()' may result in a totally legal 'None' for
            # a particular 'state_key'.
            #
            # Later: 'LABEL_BY_ADDRESS(None) --> "QUEX_GOTO_LABEL_VOID"
            return None
        else:
            return LanguageDB.ADDRESS_BY_DOOR_ID(door_id)
Example #9
0
 def ADDRESS_DROP_OUT(self, StateIndex):
     return get_address("$drop-out", StateIndex)
Example #10
0
 def ADDRESS_BY_DOOR_ID(self, DoorId):
     ## print "## %s --> %s" % (DoorId, get_address("$entry", DoorId, U=True, R=True))
     return get_address("$entry", DoorId, U=True, R=True)
Example #11
0
    def do(self, RequiredLocalVariablesDB):
        LanguageDB = Setup.language_db

        # (*) Initialize the label and variable trackers
        variable_db.init(RequiredLocalVariablesDB)
        variable_db.require("input")

        init_address_handling({})

        # (*) Pre Context State Machine
        #     (If present: All pre-context combined in single backward analyzer.)
        pre_context = self.__code_pre_context_state_machine()

        # (*) Main State Machine -- try to match core patterns
        main = self.__code_main_state_machine()

        # (*) Backward input position detection
        #     (Seldomly present -- only for Pseudo-Ambiguous Post Contexts)
        bipd = self.__code_backward_input_position_detection()

        # (*) Determine required labels and variables
        routed_address_set = get_address_set_subject_to_routing()
        routed_address_set.add(get_address("$terminal-EOF", U=True))
        routed_state_info_list = state_router_generator.get_info(
            routed_address_set)
        state_router = [state_router_generator.do(routed_state_info_list)]

        variable_db.require("target_state_index", Condition_ComputedGoto=False)

        if is_label_referenced("$reload-FORWARD") or is_label_referenced(
                "$reload-BACKWARD"):
            variable_db.require("target_state_else_index")
            variable_db.require("target_state_index")

        # Following function refers to the global 'variable_db'
        variable_definitions = self.language_db.VARIABLE_DEFINITIONS(
            variable_db)

        function_body = []
        function_body.extend(
            pre_context)  # implementation of pre-contexts (if there are some)
        function_body.extend(main)  # main pattern matcher
        function_body.extend(
            bipd)  # (seldom != empty; only for pseudo-ambiguous post contexts)
        function_body.extend(
            state_router
        )  # route to state by index (only if no computed gotos)

        # (*) Pack Pre-Context and Core State Machine into a single function
        analyzer_function = self.language_db["$analyzer-func"](
            self.state_machine_name, Setup, variable_definitions,
            function_body, self.mode_name_list)

        txt = [
            LanguageDB["$header-definitions"](LanguageDB, self.on_after_match)
        ]
        txt += get_plain_strings(analyzer_function)
        for i, element in enumerate(txt):
            if not isinstance(element, (str, unicode)):
                print element.__class__.__name__
                for k in range(max(0, i - 10)):
                    print "before:", k, txt[k]
                for k in range(i + 1, min(i + 10, len(txt))):
                    print "after: ", k, txt[k]
                assert False
        return txt
Example #12
0
def __terminal_states(StateMachineName, action_db, OnFailureAction, EndOfStreamAction, 
                      PreConditionIDList, LanguageDB, VariableDB, OnAfterMatchStr, LexemeNullObjectName):
    """NOTE: During backward-lexing, for a pre-condition, there is not need for terminal
             states, since only the flag 'pre-condition fulfilled is raised.
    """      

    # (*) specific terminal states of patterns (entered from acceptance states)
    specific_terminal_states = []
    for pattern_id, pattern_action_info in action_db.items():
        if pattern_id in PreConditionIDList: continue
        code = get_terminal_code(pattern_id, pattern_action_info, LanguageDB)
        specific_terminal_states.extend(code)

    delete_pre_context_flags = []
    for pre_context_sm_id in PreConditionIDList:
        delete_pre_context_flags.append("    ")
        delete_pre_context_flags.append(LanguageDB.ASSIGN("pre_context_%s_fulfilled_f" % __nice(pre_context_sm_id), 0))

    # If there is at least a single terminal, the the 're-entry' preparation must be accomplished
    if len(action_db) != 0: get_label("$re-start", U=True)

    #  -- execute 'on_failure' pattern action 
    #  -- goto initial state    
    end_of_stream_code_action_str = EndOfStreamAction.action().get_code()

    # -- FAILURE ACTION: Under 'normal' circumstances the on_failure action is simply to be executed
    #                    since the 'get_forward()' incremented the 'current' pointer.
    #                    HOWEVER, when end of file has been reached the 'current' pointer has to
    #                    be reset so that the initial state can drop out on the buffer limit code
    #                    and then transit to the end of file action.
    # NOTE: It is possible that 'miss' happens after a chain of characters appeared. In any case the input
    #       pointer must be setup right after the lexeme start. This way, the lexer becomes a new chance as
    #       soon as possible.
    on_failure = __terminal_on_failure_prolog(LanguageDB)
    msg        = OnFailureAction.action().get_code()

    on_failure.append(msg)

    prolog = blue_print(__terminal_state_prolog,
                        [
                          ["$$LEXEME_LENGTH$$",      LanguageDB.LEXEME_LENGTH()],
                          ["$$INPUT_P$$",            LanguageDB.INPUT_P()],
                          ["$$LEXEME_NULL_OBJECT$$", LexemeNullObjectName],
                        ]
                       )

    router = Address("$terminal-router", None,
                  [
                      blue_print(__terminal_router_prolog_str,
                      [
                       ["$$TERMINAL_FAILURE-REF$$",         "QUEX_LABEL(%i)" % get_address("$terminal-FAILURE")],
                       ["$$TERMINAL_FAILURE$$",             get_label("$terminal-FAILURE")],
                      ]),
                      # DO NOT 'U=True' for the state router. This is done automatically if 
                      # 'goto reload' is used. 
                      get_label("$state-router"), ";",
                      __terminal_router_epilog_str, 
                  ])
                     
    epilog = blue_print(__terminal_state_epilog, 
             [
              ["$$FAILURE_ACTION$$",             "".join(on_failure)],
              ["$$END_OF_STREAM_ACTION$$",       end_of_stream_code_action_str],
              ["$$TERMINAL_END_OF_STREAM-DEF$$", get_label("$terminal-EOF")],
              ["$$TERMINAL_FAILURE-DEF$$",       get_label("$terminal-FAILURE")],
              ["$$STATE_MACHINE_NAME$$",         StateMachineName],
              ["$$GOTO_START_PREPARATION$$",     get_label("$re-start", U=True)],
             ])


    reset_last_acceptance_str = ""
    if VariableDB.has_key("last_acceptance"):
        reset_last_acceptance_str = "last_acceptance = $$TERMINAL_FAILURE-REF$$; /* TERMINAL: FAILURE */"

    return_preparation = ""
    if OnAfterMatchStr != "":
        return_preparation = blue_print(__return_preparation_str,
                                        [["$$ON_AFTER_MATCH$$",  OnAfterMatchStr]])

    reentry_preparation = blue_print(__reentry_preparation_str,
                          [["$$REENTRY_PREPARATION$$",                    get_label("$re-start")],
                           ["$$DELETE_PRE_CONDITION_FULLFILLED_FLAGS$$",  "".join(delete_pre_context_flags)],
                           ["$$GOTO_START$$",                             get_label("$start", U=True)],
                           ["$$ON_AFTER_MATCH$$",                         OnAfterMatchStr],
                           ["$$RESET_LAST_ACCEPTANCE$$",                  reset_last_acceptance_str],
                           ["$$COMMENT_ON_POST_CONTEXT_INITIALIZATION$$", comment_on_post_context_position_init_str],
                           ["$$TERMINAL_FAILURE-REF$$",                   "QUEX_LABEL(%i)" % get_address("$terminal-FAILURE")],
                          ])

    txt = []
    txt.append(router)
    txt.append(prolog)
    txt.extend(specific_terminal_states)
    txt.append(epilog)
    txt.append(return_preparation)
    txt.append(reentry_preparation)

    return txt
Example #13
0
 def ADDRESS_DROP_OUT(self, StateIndex):
     return get_address("$drop-out", StateIndex)
Example #14
0
 def ADDRESS_BY_DOOR_ID(self, DoorId):
     ## print "## %s --> %s" % (DoorId, get_address("$entry", DoorId, U=True, R=True))
     return get_address("$entry", DoorId, U=True, R=True)
Example #15
0
def __terminal_states(StateMachineName, action_db, OnFailureAction,
                      EndOfStreamAction, PreConditionIDList, LanguageDB,
                      VariableDB, OnAfterMatchStr, LexemeNullObjectName):
    """NOTE: During backward-lexing, for a pre-condition, there is not need for terminal
             states, since only the flag 'pre-condition fulfilled is raised.
    """

    # (*) specific terminal states of patterns (entered from acceptance states)
    specific_terminal_states = []
    for pattern_id, pattern_action_info in action_db.items():
        if pattern_id in PreConditionIDList: continue
        code = get_terminal_code(pattern_id, pattern_action_info, LanguageDB)
        specific_terminal_states.extend(code)

    delete_pre_context_flags = []
    for pre_context_sm_id in PreConditionIDList:
        delete_pre_context_flags.append("    ")
        delete_pre_context_flags.append(
            LanguageDB.ASSIGN(
                "pre_context_%s_fulfilled_f" % __nice(pre_context_sm_id), 0))

    # If there is at least a single terminal, the the 're-entry' preparation must be accomplished
    if len(action_db) != 0: get_label("$re-start", U=True)

    #  -- execute 'on_failure' pattern action
    #  -- goto initial state
    end_of_stream_code_action_str = EndOfStreamAction.action().get_code()

    # -- FAILURE ACTION: Under 'normal' circumstances the on_failure action is simply to be executed
    #                    since the 'get_forward()' incremented the 'current' pointer.
    #                    HOWEVER, when end of file has been reached the 'current' pointer has to
    #                    be reset so that the initial state can drop out on the buffer limit code
    #                    and then transit to the end of file action.
    # NOTE: It is possible that 'miss' happens after a chain of characters appeared. In any case the input
    #       pointer must be setup right after the lexeme start. This way, the lexer becomes a new chance as
    #       soon as possible.
    on_failure = __terminal_on_failure_prolog(LanguageDB)
    msg = OnFailureAction.action().get_code()

    on_failure.append(msg)

    prolog = blue_print(__terminal_state_prolog, [
        ["$$LEXEME_LENGTH$$", LanguageDB.LEXEME_LENGTH()],
        ["$$INPUT_P$$", LanguageDB.INPUT_P()],
        ["$$LEXEME_NULL_OBJECT$$", LexemeNullObjectName],
    ])

    router = Address(
        "$terminal-router",
        None,
        [
            blue_print(__terminal_router_prolog_str, [
                [
                    "$$TERMINAL_FAILURE-REF$$",
                    "QUEX_LABEL(%i)" % get_address("$terminal-FAILURE")
                ],
                ["$$TERMINAL_FAILURE$$",
                 get_label("$terminal-FAILURE")],
            ]),
            # DO NOT 'U=True' for the state router. This is done automatically if
            # 'goto reload' is used.
            get_label("$state-router"),
            ";",
            __terminal_router_epilog_str,
        ])

    epilog = blue_print(__terminal_state_epilog, [
        ["$$FAILURE_ACTION$$", "".join(on_failure)],
        ["$$END_OF_STREAM_ACTION$$", end_of_stream_code_action_str],
        ["$$TERMINAL_END_OF_STREAM-DEF$$",
         get_label("$terminal-EOF")],
        ["$$TERMINAL_FAILURE-DEF$$",
         get_label("$terminal-FAILURE")],
        ["$$STATE_MACHINE_NAME$$", StateMachineName],
        ["$$GOTO_START_PREPARATION$$",
         get_label("$re-start", U=True)],
    ])

    reset_last_acceptance_str = ""
    if VariableDB.has_key("last_acceptance"):
        reset_last_acceptance_str = "last_acceptance = $$TERMINAL_FAILURE-REF$$; /* TERMINAL: FAILURE */"

    return_preparation = ""
    if OnAfterMatchStr != "":
        return_preparation = blue_print(
            __return_preparation_str,
            [["$$ON_AFTER_MATCH$$", OnAfterMatchStr]])

    reentry_preparation = blue_print(__reentry_preparation_str, [
        ["$$REENTRY_PREPARATION$$",
         get_label("$re-start")],
        [
            "$$DELETE_PRE_CONDITION_FULLFILLED_FLAGS$$",
            "".join(delete_pre_context_flags)
        ],
        ["$$GOTO_START$$", get_label("$start", U=True)],
        ["$$ON_AFTER_MATCH$$", OnAfterMatchStr],
        ["$$RESET_LAST_ACCEPTANCE$$", reset_last_acceptance_str],
        [
            "$$COMMENT_ON_POST_CONTEXT_INITIALIZATION$$",
            comment_on_post_context_position_init_str
        ],
        [
            "$$TERMINAL_FAILURE-REF$$",
            "QUEX_LABEL(%i)" % get_address("$terminal-FAILURE")
        ],
    ])

    txt = []
    txt.append(router)
    txt.append(prolog)
    txt.extend(specific_terminal_states)
    txt.append(epilog)
    txt.append(return_preparation)
    txt.append(reentry_preparation)

    return txt
Example #16
0
def get_skipper(TriggerSet):
    """This function implements simple 'skipping' in the sense of passing by
       characters that belong to a given set of characters--the TriggerSet.
    """
    global template_str
    assert TriggerSet.__class__.__name__ == "NumberSet"
    assert not TriggerSet.is_empty()

    LanguageDB = Setup.language_db

    skipper_index = sm_index.get()

    # Mini trigger map:  [ trigger set ] --> loop start
    # That means: As long as characters of the trigger set appear, we go to the loop start.
    transition_map = TransitionMap(
    )  # (don't worry about 'drop-out-ranges' etc.)
    transition_map.add_transition(TriggerSet, skipper_index)
    # On buffer limit code, the skipper must transit to a dedicated reloader

    goto_loop_str = [
        LanguageDB.INPUT_P_INCREMENT(),
        " goto _%s_LOOP;\n" % skipper_index
    ]
    trigger_map = transition_map.get_trigger_map()
    for i, info in enumerate(trigger_map):
        interval, target = info
        if target == E_StateIndices.DROP_OUT: continue
        trigger_map[i] = (interval, TextTransitionCode(goto_loop_str))

    iteration_code = []
    transition_block.do(iteration_code,
                        trigger_map,
                        skipper_index,
                        E_EngineTypes.ELSE,
                        GotoReload_Str="goto %s;" %
                        get_label("$reload", skipper_index))

    tmp = []
    LanguageDB.COMMENT(tmp,
                       "Skip any character in " + TriggerSet.get_utf8_string())
    comment_str = "".join(tmp)

    # Line and column number counting
    prolog = __lc_counting_replacements(prolog_txt, TriggerSet)
    epilog = __lc_counting_replacements(epilog_txt, TriggerSet)

    prolog = blue_print(prolog, [
        ["$$DELIMITER_COMMENT$$", comment_str],
        ["$$SKIPPER_INDEX$$", "%i" % skipper_index],
        ["$$INPUT_GET$$", LanguageDB.ACCESS_INPUT()],
    ])

    epilog = blue_print(
        epilog,
        [
            ["$$INPUT_P_INCREMENT$$",
             LanguageDB.INPUT_P_INCREMENT()],
            ["$$INPUT_P_DECREMENT$$",
             LanguageDB.INPUT_P_DECREMENT()],
            [
                "$$IF_INPUT_EQUAL_DELIMITER_0$$",
                LanguageDB.IF_INPUT("==", "SkipDelimiter$$SKIPPER_INDEX$$[0]")
            ],
            ["$$ENDIF$$", LanguageDB.END_IF()],
            ["$$LOOP_REENTRANCE$$",
             LanguageDB.LABEL(skipper_index)],
            ["$$BUFFER_LIMIT_CODE$$", LanguageDB.BUFFER_LIMIT_CODE],
            ["$$RELOAD$$", get_label("$reload", skipper_index)],
            [
                "$$DROP_OUT_DIRECT$$",
                get_label("$drop-out", skipper_index, U=True)
            ],
            ["$$SKIPPER_INDEX$$", "%i" % skipper_index],
            [
                "$$LABEL_TERMINAL_EOF$$",
                "QUEX_LABEL(%i)" % get_address("$terminal-EOF", U=True)
            ],
            [
                "$$LABEL_REF_AFTER_RELOAD$$",
                "QUEX_LABEL(%i)" %
                get_address("$skipper-reload", skipper_index, U=True)
            ],
            ["$$GOTO_TERMINAL_EOF$$",
             get_label("$terminal-EOF", U=True)],
            [
                "$$LABEL_AFTER_RELOAD$$",
                get_label("$skipper-reload", skipper_index)
            ],
            # 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_START$$", get_label("$start", U=True)],
            ["$$MARK_LEXEME_START$$",
             LanguageDB.LEXEME_START_SET()],
        ])

    code = [prolog]
    code.extend(iteration_code)
    code.append(epilog)

    local_variable_db = {}
    variable_db.enter(local_variable_db,
                      "reference_p",
                      Condition="QUEX_OPTION_COLUMN_NUMBER_COUNTING")

    return code, local_variable_db
Example #17
0
def get_skipper(TriggerSet):
    """This function implements simple 'skipping' in the sense of passing by
       characters that belong to a given set of characters--the TriggerSet.
    """
    global template_str
    assert TriggerSet.__class__.__name__ == "NumberSet"
    assert not TriggerSet.is_empty()

    LanguageDB = Setup.language_db

    skipper_index   = sm_index.get()

    # Mini trigger map:  [ trigger set ] --> loop start
    # That means: As long as characters of the trigger set appear, we go to the loop start.
    transition_map = TransitionMap() # (don't worry about 'drop-out-ranges' etc.)
    transition_map.add_transition(TriggerSet, skipper_index)
    # On buffer limit code, the skipper must transit to a dedicated reloader

    goto_loop_str = [LanguageDB.INPUT_P_INCREMENT(), " goto _%s_LOOP;\n" % skipper_index]
    trigger_map = transition_map.get_trigger_map()
    for i, info in enumerate(trigger_map):
        interval, target = info
        if target == E_StateIndices.DROP_OUT: continue
        trigger_map[i] = (interval, TextTransitionCode(goto_loop_str))

    iteration_code = []
    transition_block.do(iteration_code, 
                        trigger_map, 
                        skipper_index, 
                        E_EngineTypes.ELSE,
                        GotoReload_Str="goto %s;" % get_label("$reload", skipper_index))

    tmp = []
    LanguageDB.COMMENT(tmp, "Skip any character in " + TriggerSet.get_utf8_string())
    comment_str = "".join(tmp)

    # Line and column number counting
    prolog = __lc_counting_replacements(prolog_txt, TriggerSet)
    epilog = __lc_counting_replacements(epilog_txt, TriggerSet)

    prolog = blue_print(prolog,
                        [
                         ["$$DELIMITER_COMMENT$$",              comment_str],
                         ["$$SKIPPER_INDEX$$",                  "%i" % skipper_index],
                         ["$$INPUT_GET$$",                      LanguageDB.ACCESS_INPUT()],
                        ])

    epilog = blue_print(epilog,
                        [
                         ["$$INPUT_P_INCREMENT$$",              LanguageDB.INPUT_P_INCREMENT()],
                         ["$$INPUT_P_DECREMENT$$",              LanguageDB.INPUT_P_DECREMENT()],
                         ["$$IF_INPUT_EQUAL_DELIMITER_0$$",     LanguageDB.IF_INPUT("==", "SkipDelimiter$$SKIPPER_INDEX$$[0]")],
                         ["$$ENDIF$$",                          LanguageDB.END_IF()],
                         ["$$LOOP_REENTRANCE$$",                LanguageDB.LABEL(skipper_index)],
                         ["$$BUFFER_LIMIT_CODE$$",              LanguageDB.BUFFER_LIMIT_CODE],
                         ["$$RELOAD$$",                         get_label("$reload", skipper_index)],
                         ["$$DROP_OUT_DIRECT$$",                get_label("$drop-out", skipper_index, U=True)],
                         ["$$SKIPPER_INDEX$$",                  "%i" % skipper_index],
                         ["$$LABEL_TERMINAL_EOF$$",             "QUEX_LABEL(%i)" % get_address("$terminal-EOF", U=True)],
                         ["$$LABEL_REF_AFTER_RELOAD$$",         "QUEX_LABEL(%i)" % get_address("$skipper-reload", skipper_index, U=True)],
                         ["$$GOTO_TERMINAL_EOF$$",              get_label("$terminal-EOF", U=True)],
                         ["$$LABEL_AFTER_RELOAD$$",             get_label("$skipper-reload", skipper_index)],
                         # 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_START$$",                     get_label("$start", U=True)], 
                         ["$$MARK_LEXEME_START$$",              LanguageDB.LEXEME_START_SET()],
                        ])

    code = [ prolog ]
    code.extend(iteration_code)
    code.append(epilog)

    local_variable_db = {}
    variable_db.enter(local_variable_db, "reference_p", Condition="QUEX_OPTION_COLUMN_NUMBER_COUNTING")

    return code, local_variable_db