Example #1
0
    def backward_detector_function_get(self, sm):
        assert sm.get_orphaned_state_index_list() == []

        dsm = StateMachineDecorator(sm, 
                                    "BACKWARD_DETECTOR_" + repr(sm.get_id()),
                                    PostContextSM_ID_List           = [], 
                                    BackwardLexingF                 = True, 
                                    BackwardInputPositionDetectionF = True)

        variable_db.init()
        init_address_handling(dsm.get_direct_transition_to_terminal_db())

        function_body = state_machine_coder.do(dsm)

        comment = []
        if Setup.comment_state_machine_transitions_f: 
            comment = Setup.language_db["$ml-comment"]("BEGIN: BACKWARD DETECTOR STATE MACHINE\n" + \
                                                       sm.get_string(NormalizeF=False)            + \
                                                       "\nEND: BACKWARD DETECTOR STATE MACHINE")
            comment.append("\n")


        # -- input position detectors simply the next 'catch' and return
        terminal = []
        terminal.append("\n")
        terminal.append("    __quex_assert_no_passage();\n")
        terminal.append(get_label("$terminal-general-bw") + ":\n")
        terminal.append("    " + self.language_db["$input/seek_position"]("end_of_core_pattern_position") + "\n")
        terminal.append("    " + self.language_db["$input/increment"] + "\n")
        terminal.append("    return;\n")

        routed_address_set = get_address_set_subject_to_routing()

        state_router_txt = ""
        if len(routed_address_set) != 0:
            routed_state_info_list = state_router.get_info(routed_address_set, dsm)
            state_router_txt       = state_router.do(routed_state_info_list)
            variable_db.require("target_state_index", Condition_ComputedGoto=False)

        variable_db.require("input")
        variable_db.require("end_of_core_pattern_position")

        local_variable_definition = self.language_db["$local-variable-defs"](variable_db.get())

        # Put all things together
        txt = []
        txt.append(bwd_prolog.replace("$$ID$$", repr(sm.get_id()).replace("L", "")))
        txt.extend(local_variable_definition)
        txt.extend(comment)
        txt.extend(function_body)
        txt.extend(terminal)
        txt.append(state_router_txt)
        txt.append(bwd_epilog.replace("$$INIT_STATE_ID$$", get_label_of_address(sm.init_state_index)))

        return get_plain_strings(txt)
Example #2
0
    def get_code(self):
        """Template transition target states. The target state is determined at 
           run-time based on a 'state_key' for the template.
           NOTE: This handles also the recursive case.
        """
        LanguageDB = Setup.language_db

        if not self.recursive():
            label = "template_%i_target_%i[template_state_key]" % (self.template_index, self.target_index)
            get_label("$state-router", U=True) # Ensure reference of state router
            return [ "QUEX_GOTO_STATE(%s);\n" % label ]

        elif not self.uniform_state_entries_f():
            label = "template_%i_map_state_key_to_state_index[template_state_key]" % self.template_index
            get_label("$state-router", U=True) # Ensure reference of state router
            return [ "QUEX_GOTO_STATE(%s);\n" % label ]

        else:
            return [ "goto %s;" % get_label_of_address(self.template_index, U=True) ]
Example #3
0
def get_info(StateIndexList, DSM):
    LanguageDB = Setup.language_db

    # 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 #4
0
def get_info(StateIndexList, DSM):
    LanguageDB = Setup.language_db

    # 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 #5
0
    def get_code(self):
        """Template transition target states. The target state is determined at 
           run-time based on a 'state_key' for the template.
           NOTE: This handles also the recursive case.
        """
        LanguageDB = Setup.language_db

        if not self.recursive():
            label = "template_%i_target_%i[template_state_key]" % (
                self.template_index, self.target_index)
            get_label("$state-router",
                      U=True)  # Ensure reference of state router
            return ["QUEX_GOTO_STATE(%s);\n" % label]

        elif not self.uniform_state_entries_f():
            label = "template_%i_map_state_key_to_state_index[template_state_key]" % self.template_index
            get_label("$state-router",
                      U=True)  # Ensure reference of state router
            return ["QUEX_GOTO_STATE(%s);\n" % label]

        else:
            return [
                "goto %s;" % get_label_of_address(self.template_index, U=True)
            ]
Example #6
0
def __path_walker(txt, PathWalker, SMD):
    """Generates the path walker, that walks along the character sequence.
    """
    PathList     = PathWalker.path_list()
    Skeleton     = PathList[0].skeleton()
    PathWalkerID = PathWalker.core().state_index

    if PathWalker.uniform_state_entries_f():
        # (1) Input Block (get the new character)
        txt.extend(input_block.do(PathWalkerID, False, SMD))
        # (2) Acceptance information/Store Input positions
        txt.extend(acceptance_info.do(PathWalker, PathWalkerID, SMD, ForceSaveLastAcceptanceF=True))

    else:
        txt.append("    __quex_assert_no_passage();\n")
        txt.append(get_label("$entry", PathWalkerID) + ":\n")
        txt.append("    __quex_debug(\"path walker %i\");\n" % PathWalkerID)

    # (3) Transition Map

    # (3.1) The comparison with the path's current character
    #       If terminating zero is reached, the path's end state is entered.
    if PathWalker.uniform_state_entries_f():
        next_state = [ "goto %s;\n" % get_label_of_address(PathWalkerID, U=True) ]
        end_state = __end_state_router(PathWalker, SMD)
    else:
        next_state = [ __state_router(PathWalker, SMD) ]
        end_state  = ["        "] + next_state

    txt.append("    ")
    txt.append(LanguageDB["$if =="]("*path_iterator"))
    txt.append("        ")
    txt.append(LanguageDB["$increment"]("path_iterator"))
    txt.append("\n")
    txt.append("        ")
    txt.extend(next_state)
    txt.append("    ")
    txt.append(LanguageDB["$elseif"] \
               + LanguageDB["$=="]("*path_iterator", "QUEX_SETTING_PATH_TERMINATION_CODE") \
               + LanguageDB["$then"])
    txt.extend(end_state)
    txt.append("    ")
    txt.append(LanguageDB["$endif"])
    txt.append("\n")

    # (3.2) Transition map of the 'skeleton'        
    trigger_map = PathWalker.transitions().get_trigger_map()
    if len(trigger_map) == 0:
        # (This happens, for example, if there are only keywords and no 
        #  'overlaying' identifier pattern.)

        # Even if the skeleton/trigger map is empty there must be something
        # that catches the 'buffer limit code'. 
        # => Define an 'all drop out' trigger_map and then,
        # => Adapt the trigger map, so that the 'buffer limit' is an 
        #    isolated single interval.
        trigger_map = [ (Interval(-sys.maxint, sys.maxint), None) ]

    state_index_str = None
    if not PathWalker.uniform_state_entries_f():
        state_index_str = "path_walker_%i_state[path_iterator - path_walker_%i_base]" % (PathWalkerID, PathWalkerID)

    txt.extend(transition_block.do(trigger_map, PathWalkerID, SMD, ReturnToState_Str=state_index_str))

    # (4) The drop out (nothing matched)
    #     (Path iterator has not been increased yet)

    txt.extend(drop_out.do(PathWalker, PathWalkerID, SMD))

    return 
Example #7
0
def __state_entries(txt, PathWalker, SMD):
    """Defines the entries of the path's states, so that the state key
       for the template is set, before the jump into the template. E.g.

            STATE_4711: 
               path_iterator = path_23 + 0; goto PATHWALKER_23;
            STATE_3123: 
               path_iterator = path_23 + 1; goto PATHWALKER_23;
            STATE_8912: 
               path_iterator = path_23 + 2; goto PATHWALKER_23;
    """
    sm = SMD.sm()

    PathN = len(PathWalker.path_list())
    require_path_end_state_variable_f = False
    txt.append("\n")
    for path in PathWalker.path_list():
        prev_state_index = None
        # Last state of sequence is not in the path, it is the first state after.
        for i, info in enumerate(path.sequence()[:-1]):
            state_index = info[0]
            # No need for state router if:
            #   (i) PathWalker is uniform, because then even after reload no dedicated
            #       state entry is required.
            #   (ii) The state is not entered from any other state except the predecessor
            #        on the path.
            # But:
            #   The first state always needs an entry.
            if prev_state_index != None:
                candidate = sm.get_only_entry_to_state(state_index)
                if PathWalker.uniform_state_entries_f() and prev_state_index == candidate:
                    prev_state_index = state_index
                    continue

            state = SMD.sm().states[state_index]

            entry_txt = []
            if PathWalker.uniform_state_entries_f():
                # If all state entries are uniform, the entry handling happens uniformly at
                # the entrance of the template, not each state.
                label_str = get_label("$entry", state_index) + ":\n"
                if state_index != SMD.sm().init_state_index:
                    label_str = "    __quex_assert_no_passage();\n" + label_str

                entry_txt.append(label_str)
                entry_txt.append("    ")
                entry_txt.append(LanguageDB["$debug-state"](state_index, SMD.forward_lexing_f()))
            else:
                entry_txt.extend(input_block.do(state_index, False, SMD))
                entry_txt.extend(acceptance_info.do(state, state_index, SMD, ForceSaveLastAcceptanceF=True))

            if PathWalker.uniform_state_entries_f() and PathN != 1:
                require_path_end_state_variable_f = True
                end_state_index = path.sequence()[-1][0]
                entry_txt.append("    path_end_state                 = QUEX_LABEL(%i);\n" \
                                 % get_address("$entry", end_state_index, U=True, R=True))
                
            entry_txt.append("    ")
            entry_txt.append(LanguageDB["$assignment"](
                                       "path_iterator                 ", 
                                       "path_%i + %i" % (path.index(), i)))
            entry_txt.append("goto %s;\n\n" % get_label_of_address(PathWalker.core().state_index, U=True))

            txt.append(Address("$entry", state_index, Code=entry_txt))
            prev_state_index = state_index

    return require_path_end_state_variable_f
Example #8
0
    def backward_detector_function_get(self, sm):
        assert sm.get_orphaned_state_index_list() == []

        dsm = StateMachineDecorator(sm,
                                    "BACKWARD_DETECTOR_" + repr(sm.get_id()),
                                    PostContextSM_ID_List=[],
                                    BackwardLexingF=True,
                                    BackwardInputPositionDetectionF=True)

        variable_db.init()
        init_address_handling(dsm.get_direct_transition_to_terminal_db())

        function_body = state_machine_coder.do(dsm)

        comment = []
        if Setup.comment_state_machine_transitions_f:
            comment = Setup.language_db["$ml-comment"]("BEGIN: BACKWARD DETECTOR STATE MACHINE\n" + \
                                                       sm.get_string(NormalizeF=False)            + \
                                                       "\nEND: BACKWARD DETECTOR STATE MACHINE")
            comment.append("\n")

        # -- input position detectors simply the next 'catch' and return
        terminal = []
        terminal.append("\n")
        terminal.append("    __quex_assert_no_passage();\n")
        terminal.append(get_label("$terminal-general-bw") + ":\n")
        terminal.append("    " + self.language_db["$input/seek_position"]
                        ("end_of_core_pattern_position") + "\n")
        terminal.append("    " + self.language_db["$input/increment"] + "\n")
        terminal.append("    return;\n")

        routed_address_set = get_address_set_subject_to_routing()

        state_router_txt = ""
        if len(routed_address_set) != 0:
            routed_state_info_list = state_router.get_info(
                routed_address_set, dsm)
            state_router_txt = state_router.do(routed_state_info_list)
            variable_db.require("target_state_index",
                                Condition_ComputedGoto=False)

        variable_db.require("input")
        variable_db.require("end_of_core_pattern_position")

        local_variable_definition = self.language_db["$local-variable-defs"](
            variable_db.get())

        # Put all things together
        txt = []
        txt.append(
            bwd_prolog.replace("$$ID$$",
                               repr(sm.get_id()).replace("L", "")))
        txt.extend(local_variable_definition)
        txt.extend(comment)
        txt.extend(function_body)
        txt.extend(terminal)
        txt.append(state_router_txt)
        txt.append(
            bwd_epilog.replace("$$INIT_STATE_ID$$",
                               get_label_of_address(sm.init_state_index)))

        return get_plain_strings(txt)