Exemple #1
0
def do(SMD, UniformOnlyF):
    """UniformOnlyF --> Accept only uniform states in path.
                        (This must be done by the 'analyzer module' too.)
    
       RETURNS: Array 'x'

       x[0] transition target definitions in terms of a 
            local variable database
       x[1] code for templates and state entries
       x[2] involved_state_index_list
    """
    assert isinstance(SMD, StateMachineDecorator)
          
    # (1) Find possible state combinations
    path_list = paths.do(SMD.sm(), UniformOnlyF)
    for path in path_list:
        involved_state_index_list = map(lambda info: info[0], path.sequence())

    # (2) Implement code for template combinations
    code, involved_state_index_list = _do(path_list, SMD, UniformOnlyF)

    if len(involved_state_index_list) != 0:
        variable_db.require("path_iterator")

    transition_block.format_this(code)

    return code, \
           involved_state_index_list
Exemple #2
0
def __path_definition(PathWalker, SMD):
    """Defines the transition targets for each involved state.
    """
    PathWalkerID = PathWalker.core().state_index
    PathList     = PathWalker.path_list()
    PathN        = len(PathList)

    def __get_state_list():
        result = []
        for path in PathList:
            Sequence = path.sequence()
            for state_index, dummy in Sequence[:-1]:
                result.append("QUEX_LABEL(%i), " % get_address("$entry", state_index, R=True, U=True))

            end_state_index = Sequence[-1][0]
            # If 'end_state_index' belongs to a non-implemented dead-end-state
            # => 'get_real_address()' returns address of immediately entered terminal
            end_state_label = "QUEX_LABEL(%i), " % get_address("$entry", end_state_index, R=True, U=True)
            result.append(end_state_label)
        return result

    memory       = ["\n"]
    memory_index = 0
    for path in PathList:
        Sequence = path.sequence()
        L        = len(Sequence)

        # Last element of sequence contains only the 'end state'.
        memory.append("    ")
        sequence_str = []
        for state_index, character in Sequence[:-1]:
            memory.append("%i, " % character)
            sequence_str.append(Interval(character).get_utf8_string())
        memory.append("QUEX_SETTING_PATH_TERMINATION_CODE, ")
        memory.append(LanguageDB["$comment"]("".join(sequence_str)) + "\n")

        variable_db.require("path_%i", 
                            Initial = "path_walker_%i_base + %i" % (PathWalkerID, memory_index), 
                            Index   = path.index())

        memory_index += L

    # (*) Path Walker Basis
    # The 'base' must be defined before all --> PriorityF (see table in variable_db)
    variable_db.require_array("path_walker_%i_base", 
                              ElementN = memory_index + 1,
                              Initial  = ["{"] + memory + ["\n    }"],
                              Index    = PathWalkerID)
    
    # (*) The State Information for each path step
    if not PathWalker.uniform_state_entries_f():
        state_list = __get_state_list()
        variable_db.require_array("path_walker_%i_state", 
                                  ElementN = len(state_list), 
                                  Initial  = ["{"] + state_list + ["}"], 
                                  Index    = PathWalkerID)
Exemple #3
0
def __local_variable_definition(PostContextID_List, PreContextID_List, LanguageDB):
    PostContextN = len(PostContextID_List)

    variable_db.require("last_acceptance", 
                        Initial="QUEX_LABEL(%i)" % get_address("$terminal-FAILURE"))
    variable_db.require("last_acceptance_input_position") 
    variable_db.require_array("post_context_start_position",    
                              ElementN = PostContextN, 
                              Initial  = "{ " + ("0, " * (PostContextN - 1) + "0") + "}")
    variable_db.require("PostContextStartPositionN", 
                        Initial = "(size_t)" + repr(PostContextN))
    variable_db.require("input") 
              
    # -- pre-condition fulfillment flags                
    for sm_id in PreContextID_List:
        variable_db.require("pre_context_%i_fulfilled_f", Index = sm_id)

    return LanguageDB["$local-variable-defs"](variable_db.get())
Exemple #4
0
def __local_variable_definition(PostContextID_List, PreContextID_List,
                                LanguageDB):
    PostContextN = len(PostContextID_List)

    variable_db.require("last_acceptance",
                        Initial="QUEX_LABEL(%i)" %
                        get_address("$terminal-FAILURE"))
    variable_db.require("last_acceptance_input_position")
    variable_db.require_array("post_context_start_position",
                              ElementN=PostContextN,
                              Initial="{ " + ("0, " *
                                              (PostContextN - 1) + "0") + "}")
    variable_db.require("PostContextStartPositionN",
                        Initial="(size_t)" + repr(PostContextN))
    variable_db.require("input")

    # -- pre-condition fulfillment flags
    for sm_id in PreContextID_List:
        variable_db.require("pre_context_%i_fulfilled_f", Index=sm_id)

    return LanguageDB["$local-variable-defs"](variable_db.get())
Exemple #5
0
def do(SMD, CostCoefficient):
    """RETURNS: Array 'x'

       x[0] transition target definitions in terms of a 
            local variable database
       x[1] code for templates and state entries
       x[2] state router for template targets
       x[3] involved_state_index_list
    """
    assert isinstance(SMD, StateMachineDecorator)

    # (1) Find possible state combinations
    combination_list = templates.do(SMD.sm(), CostCoefficient)

    # (2) Implement code for template combinations
    code,                     \
    involved_state_index_list = _do(combination_list, SMD)

    if len(involved_state_index_list) != 0:
        variable_db.require("template_state_key")

    return code, involved_state_index_list
Exemple #6
0
def do(SMD, CostCoefficient):
    """RETURNS: Array 'x'

       x[0] transition target definitions in terms of a 
            local variable database
       x[1] code for templates and state entries
       x[2] state router for template targets
       x[3] involved_state_index_list
    """
    assert isinstance(SMD, StateMachineDecorator)
          
    # (1) Find possible state combinations
    combination_list = templates.do(SMD.sm(), CostCoefficient)

    # (2) Implement code for template combinations
    code,                     \
    involved_state_index_list = _do(combination_list, SMD)

    if len(involved_state_index_list) != 0:
        variable_db.require("template_state_key")

    return code, involved_state_index_list
Exemple #7
0
    def analyzer_function_get(self, RequiredLocalVariablesDB):
        routed_address_set = set([])
        function_body = []

        # (*) Core State Machine
        #     All pattern detectors combined in single forward analyzer
        dsm = StateMachineDecorator(self.sm,
                                    self.state_machine_name,
                                    self.post_contexted_sm_id_list,
                                    BackwardLexingF=False,
                                    BackwardInputPositionDetectionF=False)

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

        # (*) Pre Context State Machine
        #     All pre-context combined in single backward analyzer.
        if self.pre_context_sm_list != []:
            code = self.__backward_analyzer()
            function_body.extend(code)

        # -- now, consider core state machine
        code = self.__forward_analyzer(dsm)
        function_body.extend(code)

        # At this point in time, the function body is completely defined
        routed_address_set = get_address_set_subject_to_routing()

        if len(routed_address_set) != 0 or is_label_referenced(
                "$state-router"):
            routed_state_info_list = state_router.get_info(
                routed_address_set, dsm)
            function_body.append(state_router.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"](
            self.post_contexted_sm_id_list, self.pre_context_sm_id_list,
            self.language_db)

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

        return get_plain_strings(analyzer_function)
Exemple #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)
Exemple #9
0
    def analyzer_function_get(self, RequiredLocalVariablesDB):
        routed_address_set = set([])
        function_body      = []

        # (*) Core State Machine
        #     All pattern detectors combined in single forward analyzer
        dsm = StateMachineDecorator(self.sm, 
                                    self.state_machine_name, 
                                    self.post_contexted_sm_id_list, 
                                    BackwardLexingF=False, 
                                    BackwardInputPositionDetectionF=False)

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

        # (*) Pre Context State Machine
        #     All pre-context combined in single backward analyzer.
        if self.pre_context_sm_list != []:
            code = self.__backward_analyzer()
            function_body.extend(code)
            
        # -- now, consider core state machine
        code = self.__forward_analyzer(dsm)
        function_body.extend(code)

        # At this point in time, the function body is completely defined
        routed_address_set = get_address_set_subject_to_routing()

        if len(routed_address_set) != 0 or is_label_referenced("$state-router"):
            routed_state_info_list = state_router.get_info(routed_address_set, dsm)
            function_body.append(state_router.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"](self.post_contexted_sm_id_list,
                                                                         self.pre_context_sm_id_list, 
                                                                         self.language_db)

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

        return get_plain_strings(analyzer_function)
Exemple #10
0
def _do(PathList, SMD, UniformOnlyF):
    """-- Returns generated code for all templates.
       -- Sets the template_compression_db in SMD.
    """
    global LanguageDB 

    assert type(PathList) == list
    assert isinstance(SMD, StateMachineDecorator)

    LanguageDB = Setup.language_db
    state_db   = SMD.sm().states
    SM_ID      = SMD.sm().get_id()

    def __equal(SkeletonA, SkeletonB):
        if len(SkeletonA) != len(SkeletonB): return False

        for key, trigger_set in SkeletonA.items():
            if SkeletonB.has_key(key) == False: return False
            if not trigger_set.is_equal(SkeletonB[key]): return False
        return True

    def __add_to_matching_path(path, path_db):
        assert isinstance(path, paths.CharacterPath)
        assert isinstance(path_db, dict)

        prototype_state = state_db[path.sequence()[0][0]]
        for index, path_list in path_db.items():
            # If uniformity is required, only such paths can be combined
            # where the states are uniform with each other. Assume that 
            # the states inside a path are 'uniform', so only one state
            # of each as to be checked.
            path_list_prototype_state = state_db[path_list[0].sequence()[0][0]] 
            if UniformOnlyF and not prototype_state.is_equivalent(path_list_prototype_state): 
                continue
                
            for candidate in path_list:
                # Compare the skeletons (remaining trigger maps)
                if __equal(path.skeleton(), candidate.skeleton()):
                    path_list.append(path)
                    return True
        return False

    # -- Sort the paths according their skeleton. Paths with the 
    #    same skeleton will use the same pathwalker.
    path_db                = {}
    for candidate in PathList:
        assert isinstance(candidate, paths.CharacterPath)
        # Is there a path with the same skeleton?
        if __add_to_matching_path(candidate, path_db): continue
        # If there is no equivalent path, then add a new 'prototype'
        path_walker_state_index = index.get()
        path_db[path_walker_state_index] = [ candidate ]

    # -- Create 'PathWalkerState' objects that can mimik state machine states.
    # -- Collect all indices of states involved in paths
    involved_state_index_list = set([])
    path_walker_list          = []
    for state_index, path_list in path_db.items():
        # Two Scenarios for settings at state entry (last_acceptance_position, ...)
        # 
        #   (i) All state entries are uniform: 
        #       -- Then, a representive state entry can be implemented at the 
        #          template entry. 
        #       -- Recursion happens to the template entry.
        #
        #   (ii) One or more state entry are different (non-uniform):
        #       -- The particularities of each state entry need to be implemented
        #          at state entry.
        #       -- Recursion is routed to entries of involved states.
        #      
        # The last state in sequence is the end target state, which cannot be 
        # addressed inside the pathwalker. It is the first state after the path.
        for path in path_list:
            involved_state_list = map(lambda info: info[0], path.sequence())
            involved_state_index_list.update(involved_state_list[:-1])

        # -- Determine if all involved states are uniform
        prototype = template_coder.get_uniform_prototype(SMD, involved_state_index_list)

        path_walker_list.append(PathWalkerState(path_list, SM_ID, state_index, prototype))

        for path in path_list:
            final_state_index = map(lambda info: info[0], path.sequence())[-1]
            # Allways be able to route to the end-state(?)

    # -- Generate code for:
    #      -- related variables: paths for pathwalkers
    #      -- state entries
    #      -- the pathwalkers
    code        = []
    router_code = []
    for path_walker in path_walker_list:
        __path_definition(path_walker, SMD) 
        if __state_entries(code, path_walker, SMD): 
            variable_db.require("path_end_state")
        __path_walker(code, path_walker, SMD)

    return code, involved_state_index_list
Exemple #11
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)