Beispiel #1
0
def __template_state(txt, TheTemplate, SMD):
    """Generate the template state that 'hosts' the templated states.
    """
    state = TheTemplate
    state_index = TheTemplate.core().state_index
    TriggerMap = state.transitions().get_trigger_map()

    if TheTemplate.uniform_state_entries_f():
        txt.extend(input_block.do(state_index, False, SMD))
        txt.extend(
            acceptance_info.do(state,
                               state_index,
                               SMD,
                               ForceSaveLastAcceptanceF=True))
    else:
        label_str = "    __quex_assert_no_passage();\n" + \
                    get_label("$entry", state_index) + ":\n"
        txt.append(label_str)

    state_index_str = None
    if not TheTemplate.uniform_state_entries_f():
        # Templates that need to implement more than one state need to return to
        # dedicated state entries, if the state entries are not uniform.
        state_index_str = "template_%i_map_state_key_to_state_index[template_state_key]" % state_index

    txt.extend(
        transition_block.do(TriggerMap,
                            state_index,
                            SMD,
                            ReturnToState_Str=state_index_str))

    txt.extend(drop_out.do(state, state_index, SMD))
Beispiel #2
0
def __template_state(txt, TheTemplate, SMD):
    """Generate the template state that 'hosts' the templated states.
    """
    state       = TheTemplate
    state_index = TheTemplate.core().state_index
    TriggerMap  = state.transitions().get_trigger_map()


    if TheTemplate.uniform_state_entries_f():
        txt.extend(input_block.do(state_index, False, SMD))
        txt.extend(acceptance_info.do(state, state_index, SMD, ForceSaveLastAcceptanceF=True))
    else:
        label_str = "    __quex_assert_no_passage();\n" + \
                    get_label("$entry", state_index) + ":\n"
        txt.append(label_str)

    state_index_str = None
    if not TheTemplate.uniform_state_entries_f():
        # Templates that need to implement more than one state need to return to
        # dedicated state entries, if the state entries are not uniform.
        state_index_str = "template_%i_map_state_key_to_state_index[template_state_key]" % state_index

    txt.extend(transition_block.do(TriggerMap, state_index, SMD, ReturnToState_Str=state_index_str))

    txt.extend(drop_out.do(state, state_index, SMD))
Beispiel #3
0
def __templated_state_entries(txt, TheTemplate, SMD):
    """Defines the entries of templated states, so that the state key
       for the template is set, before the jump into the template. E.g.

            STATE_4711: 
               key = 0; goto TEMPLATE_STATE_111;
            STATE_3123: 
               key = 1; goto TEMPLATE_STATE_111;
            STATE_8912: 
               key = 2; goto TEMPLATE_STATE_111;
    """
    for key, state_index in enumerate(TheTemplate.template_combination().involved_state_list()):
        state = SMD.sm().states[state_index]

        if TheTemplate.uniform_state_entries_f():
            if state_index != SMD.sm().init_state_index:
                txt.append("    __quex_assert_no_passage();\n")
            txt.append(get_label("$entry", state_index) + ":\n")
            txt.append("\n    " + LanguageDB["$debug-state"](state_index, SMD.forward_lexing_f())) 
        else:
            # If all state entries are uniform, the entry handling happens uniformly at
            # the entrance of the template, not each state.
            txt.extend(input_block.do(state_index, False, SMD))
            txt.extend(acceptance_info.do(state, state_index, SMD, ForceSaveLastAcceptanceF=True))

        txt.append("    ")
        txt.append(LanguageDB["$assignment"]("template_state_key", "%i" % key).replace("\n", "\n    "))
        txt.append("    goto %s;" % get_label("$entry", TheTemplate.core().state_index, U=True))
        txt.append("\n\n")
Beispiel #4
0
def do(state, StateIdx, SMD=False):
    """Produces code for all state transitions. Programming language is determined
       by 'Language'.
    """    
    assert isinstance(state, State)
    assert SMD.__class__.__name__   == "StateMachineDecorator"
    assert len(state.transitions().get_epsilon_target_state_index_list()) == 0, \
           "Epsilon transition contained target states: state machine was not made a DFA!\n" + \
           "Epsilon target states = " + repr(state.transitions().get_epsilon_target_state_index_list())
    InitStateF = StateIdx == SMD.sm().init_state_index

    LanguageDB = Setup.language_db

    # (*) Dead End States 
    #     i.e. states with no further transitions.
    dead_end_state_info = SMD.dead_end_state_db().get(StateIdx)
    if dead_end_state_info != None:
        state_stub = __dead_end_state_stub(dead_end_state_info, SMD)
        # Some states do not need 'stubs' to terminal since they are straight
        # forward transitions to the terminal.
        if len(state_stub) == 0: return []
        return [ get_label("$entry", StateIdx), ":\n",
                "    ", LanguageDB["$debug-state"](StateIdx, SMD.forward_lexing_f())
               ] + state_stub 
        

    # (*) Normal States
    TriggerMap = state.transitions().get_trigger_map()
    assert TriggerMap != []  # Only dead end states have empty trigger maps.
    #                        # => Here, the trigger map cannot be empty.

    txt = []
    txt.extend(input_block.do(StateIdx, InitStateF, SMD))
    txt.extend(acceptance_info.do(state, StateIdx, SMD))
    txt.extend(transition_block.do(TriggerMap, StateIdx, SMD))
    txt.extend(drop_out.do(state, StateIdx, SMD))
    txt.extend(get_epilog(StateIdx, InitStateF, SMD))
    
    return txt 
Beispiel #5
0
def do(state, StateIdx, SMD=False):
    """Produces code for all state transitions. Programming language is determined
       by 'Language'.
    """
    assert isinstance(state, State)
    assert SMD.__class__.__name__ == "StateMachineDecorator"
    assert len(state.transitions().get_epsilon_target_state_index_list()) == 0, \
           "Epsilon transition contained target states: state machine was not made a DFA!\n" + \
           "Epsilon target states = " + repr(state.transitions().get_epsilon_target_state_index_list())
    InitStateF = StateIdx == SMD.sm().init_state_index

    LanguageDB = Setup.language_db

    # (*) Dead End States
    #     i.e. states with no further transitions.
    dead_end_state_info = SMD.dead_end_state_db().get(StateIdx)
    if dead_end_state_info != None:
        state_stub = __dead_end_state_stub(dead_end_state_info, SMD)
        # Some states do not need 'stubs' to terminal since they are straight
        # forward transitions to the terminal.
        if len(state_stub) == 0: return []
        return [
            get_label("$entry", StateIdx), ":\n", "    ",
            LanguageDB["$debug-state"](StateIdx, SMD.forward_lexing_f())
        ] + state_stub

    # (*) Normal States
    TriggerMap = state.transitions().get_trigger_map()
    assert TriggerMap != []  # Only dead end states have empty trigger maps.
    #                        # => Here, the trigger map cannot be empty.

    txt = []
    txt.extend(input_block.do(StateIdx, InitStateF, SMD))
    txt.extend(acceptance_info.do(state, StateIdx, SMD))
    txt.extend(transition_block.do(TriggerMap, StateIdx, SMD))
    txt.extend(drop_out.do(state, StateIdx, SMD))
    txt.extend(get_epilog(StateIdx, InitStateF, SMD))

    return txt
Beispiel #6
0
def __templated_state_entries(txt, TheTemplate, SMD):
    """Defines the entries of templated states, so that the state key
       for the template is set, before the jump into the template. E.g.

            STATE_4711: 
               key = 0; goto TEMPLATE_STATE_111;
            STATE_3123: 
               key = 1; goto TEMPLATE_STATE_111;
            STATE_8912: 
               key = 2; goto TEMPLATE_STATE_111;
    """
    for key, state_index in enumerate(
            TheTemplate.template_combination().involved_state_list()):
        state = SMD.sm().states[state_index]

        if TheTemplate.uniform_state_entries_f():
            if state_index != SMD.sm().init_state_index:
                txt.append("    __quex_assert_no_passage();\n")
            txt.append(get_label("$entry", state_index) + ":\n")
            txt.append("\n    " + LanguageDB["$debug-state"]
                       (state_index, SMD.forward_lexing_f()))
        else:
            # If all state entries are uniform, the entry handling happens uniformly at
            # the entrance of the template, not each state.
            txt.extend(input_block.do(state_index, False, SMD))
            txt.extend(
                acceptance_info.do(state,
                                   state_index,
                                   SMD,
                                   ForceSaveLastAcceptanceF=True))

        txt.append("    ")
        txt.append(LanguageDB["$assignment"]("template_state_key",
                                             "%i" % key).replace(
                                                 "\n", "\n    "))
        txt.append("    goto %s;" %
                   get_label("$entry", TheTemplate.core().state_index, U=True))
        txt.append("\n\n")
Beispiel #7
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 
Beispiel #8
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