Exemplo n.º 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))
Exemplo n.º 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))
Exemplo n.º 3
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 
Exemplo n.º 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
Exemplo n.º 5
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