Exemplo n.º 1
0
def require_scheme_variable(SchemeID, Scheme, TState, StateDB):
    """Defines the transition targets for each involved state. Note, that recursion
       is handled as part of the general case, where all involved states target 
       a common door of the template state.
    """
    LanguageDB = Setup.language_db

    def get_code(AdrList):
        return "".join(["{ "] + map(lambda adr: "QUEX_LABEL(%i), " % adr, AdrList) + [" }"])

    assert len(Scheme) == len(TState.implemented_state_index_list())
    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)

    address_list = [ address(target_index, i, TState) for i, target_index in enumerate(Scheme) ]

    variable_db.require_array("template_%i_target_%i", 
                              ElementN = len(TState.implemented_state_index_list()), 
                              Initial  = get_code(address_list),
                              Index    = (TState.index, SchemeID))
Exemplo n.º 2
0
def require_position_registers(TheAnalyzer):
    """Require an array to store input positions. This has later to be 
    implemented as 'variables'. Position registers are exclusively used
    for post-context restore. No other engine than FORWARD would require
    those.
    """
    if not TheAnalyzer.engine_type.is_FORWARD(): 
        return

    if TheAnalyzer.position_register_map is None:
        position_register_n = 0
    else:
        position_register_n = len(set(TheAnalyzer.position_register_map.itervalues()))

    if position_register_n != 0:
        initial_array  = "{ " + ("0, " * (position_register_n - 1) + "0") + "}"
    else:
        # Implement a dummy array (except that there is no reload)
        if Setup.buffer_based_analyzis_f: return
        initial_array = "(void*)0"

    variable_db.require_array("position", ElementN = position_register_n,
                              Initial = initial_array)
    variable_db.require("PositionRegisterN", 
                        Initial = "(size_t)%i" % position_register_n)
Exemplo n.º 3
0
def require_position_registers(TheAnalyzer):
    """Require an array to store input positions. This has later to be 
    implemented as 'variables'. Position registers are exclusively used
    for post-context restore. No other engine than FORWARD would require
    those.
    """
    if not TheAnalyzer.engine_type.is_FORWARD():
        return

    if TheAnalyzer.position_register_map is None:
        position_register_n = 0
    else:
        position_register_n = len(
            set(TheAnalyzer.position_register_map.itervalues()))

    if position_register_n != 0:
        initial_array = "{ " + ("0, " * (position_register_n - 1) + "0") + "}"
    else:
        # Implement a dummy array (except that there is no reload)
        if Setup.buffer_based_analyzis_f: return
        initial_array = "(void*)0"

    variable_db.require_array("position",
                              ElementN=position_register_n,
                              Initial=initial_array)
    variable_db.require("PositionRegisterN",
                        Initial="(size_t)%i" % position_register_n)
Exemplo n.º 4
0
    def __code_main_state_machine(self):
        assert len(self.sm.get_orphaned_state_index_list()) == 0

        LanguageDB = self.language_db 
        txt        = []

        # -- [optional] comment state machine transitions 
        if Setup.comment_state_machine_f:
            LanguageDB.ML_COMMENT(txt, 
                                  "BEGIN: STATE MACHINE\n"             + \
                                  self.sm.get_string(NormalizeF=False) + \
                                  "END: STATE MACHINE") 
            txt.append("\n") # For safety: New content may have to start in a newline, e.g. "#ifdef ..."

        # -- implement the state machine itself
        analyzer           = analyzer_generator.do(self.sm, E_EngineTypes.FORWARD)
        state_machine_code = state_machine_coder.do(analyzer)
        txt.extend(state_machine_code)

        lexeme_null_object_name = "QUEX_NAME(LexemeNullObject)"
        if Setup.external_lexeme_null_object != "":
            lexeme_null_object_name = Setup.external_lexeme_null_object

        # -- terminal states: execution of pattern actions  
        terminal_code = LanguageDB["$terminal-code"](self.state_machine_name,
                                                     self.action_db, 
                                                     self.on_failure_action, 
                                                     self.on_end_of_stream_action, 
                                                     self.pre_context_sm_id_list,
                                                     self.language_db, 
                                                     variable_db,
                                                     self.on_after_match, 
                                                     lexeme_null_object_name) 
        
        txt.extend(terminal_code)

        N = len(set(analyzer.position_register_map.values()))
        if len(analyzer.position_register_map) == 0:
            variable_db.require("position",          Initial = "(void*)0x0", Type = "void*")
            variable_db.require("PositionRegisterN", Initial = "(size_t)%i" % N)
        else:
            variable_db.require_array("position", ElementN = N,
                                      Initial  = "{ " + ("0, " * (N - 1) + "0") + "}")
            variable_db.require("PositionRegisterN", Initial = "(size_t)%i" % N)
    
        if analyzer.last_acceptance_variable_required():
            variable_db.require("last_acceptance")

        # -- reload definition (forward, backward, init state reload)
        code = LanguageDB.RELOAD()
        txt.extend(code)

        return txt
Exemplo n.º 5
0
def require_scheme_variable(SchemeID, Scheme, TState, StateDB):
    """Defines the transition targets for each involved state. Note, that recursion
       is handled as part of the general case, where all involved states target 
       a common door of the template state.
    """
    LanguageDB = Setup.language_db

    def get_code(AdrList):
        last_i = len(AdrList) - 1
        txt = ["{ "]
        for i, adr in enumerate(AdrList):
            if i != last_i:
                txt.append("%s, " % LanguageDB.LABEL_BY_ADDRESS(adr))
            else:
                txt.append("%s " % LanguageDB.LABEL_BY_ADDRESS(adr))
        txt.append(" }")
        return "".join(txt)

    assert len(Scheme) == len(TState.implemented_state_index_list())

    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)

    address_list = [address(target_index, state_key, TState) for state_key, target_index in enumerate(Scheme)]

    variable_db.require_array(
        "template_%i_target_%i",
        ElementN=len(TState.implemented_state_index_list()),
        Initial=get_code(address_list),
        Index=(TState.index, SchemeID),
    )
Exemplo n.º 6
0
    def __code_main_state_machine(self):
        assert len(self.sm.get_orphaned_state_index_list()) == 0

        LanguageDB = self.language_db
        txt = []

        # -- [optional] comment state machine transitions
        if Setup.comment_state_machine_f:
            LanguageDB.ML_COMMENT(txt,
                                  "BEGIN: STATE MACHINE\n"             + \
                                  self.sm.get_string(NormalizeF=False) + \
                                  "END: STATE MACHINE")
            txt.append(
                "\n"
            )  # For safety: New content may have to start in a newline, e.g. "#ifdef ..."

        # -- implement the state machine itself
        analyzer = analyzer_generator.do(self.sm, E_EngineTypes.FORWARD)
        state_machine_code = state_machine_coder.do(analyzer)
        txt.extend(state_machine_code)

        lexeme_null_object_name = "QUEX_NAME(LexemeNullObject)"
        if Setup.external_lexeme_null_object != "":
            lexeme_null_object_name = Setup.external_lexeme_null_object

        # -- terminal states: execution of pattern actions
        terminal_code = LanguageDB["$terminal-code"](
            self.state_machine_name, self.action_db, self.on_failure_action,
            self.on_end_of_stream_action, self.pre_context_sm_id_list,
            self.language_db, variable_db, self.on_after_match,
            lexeme_null_object_name)

        txt.extend(terminal_code)

        N = len(set(analyzer.position_register_map.values()))
        if len(analyzer.position_register_map) == 0:
            variable_db.require("position", Initial="(void*)0x0", Type="void*")
            variable_db.require("PositionRegisterN", Initial="(size_t)%i" % N)
        else:
            variable_db.require_array("position",
                                      ElementN=N,
                                      Initial="{ " + ("0, " * (N - 1) + "0") +
                                      "}")
            variable_db.require("PositionRegisterN", Initial="(size_t)%i" % N)

        if analyzer.last_acceptance_variable_required():
            variable_db.require("last_acceptance")

        # -- reload definition (forward, backward, init state reload)
        code = LanguageDB.RELOAD()
        txt.extend(code)

        return txt
Exemplo n.º 7
0
def require_scheme_variable(SchemeID, Scheme, TState, StateDB):
    """Defines the transition targets for each involved state. Note, that recursion
       is handled as part of the general case, where all involved states target 
       a common door of the template state.
    """
    LanguageDB = Setup.language_db

    def get_code(AdrList):
        last_i = len(AdrList) - 1
        txt = ["{ "]
        for i, adr in enumerate(AdrList):
            if i != last_i:
                txt.append("%s, " % LanguageDB.LABEL_BY_ADDRESS(adr)) 
            else:
                txt.append("%s " % LanguageDB.LABEL_BY_ADDRESS(adr)) 
        txt.append(" }")
        return "".join(txt)

    assert len(Scheme) == len(TState.implemented_state_index_list())
    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)

    address_list = [ address(target_index, state_key, TState) \
                     for state_key, target_index in enumerate(Scheme) ]

    variable_db.require_array("template_%i_target_%i", 
                              ElementN = len(TState.implemented_state_index_list()), 
                              Initial  = get_code(address_list),
                              Index    = (TState.index, SchemeID))
Exemplo n.º 8
0
def require_scheme_variable(SchemeID, SchemeIterable, TState, StateDB):
    """Defines the transition targets for each involved state. Note, that
    recursion is handled as part of the general case, where all involved states
    target a common door of the template state.
    """
    door_id_list = list(SchemeIterable)
    
    def quex_label(DoorId, LastF):
        address = dial_db.get_address_by_door_id(DoorId, RoutedF=True)
        if not LastF: return "QUEX_LABEL(%s), " % address
        else:         return "QUEX_LABEL(%s) "  % address

    txt = ["{ "]
    LastI = len(door_id_list) - 1
    txt.extend(
        quex_label(door_id, LastF=(i==LastI))
        for i, door_id in enumerate(door_id_list)
    )
    txt.append("}")

    return variable_db.require_array("template_%i_target_%i", 
                                     ElementN = len(TState.state_index_sequence()), 
                                     Initial  = "".join(txt),
                                     Index    = (TState.index, SchemeID))
Exemplo n.º 9
0
def get_skipper(OpenerSequence, CloserSequence, CloserPattern, ModeName,
                OnSkipRangeOpen, DoorIdAfter):
    assert len(OpenerSequence) >= 1
    assert len(CloserSequence) >= 1
    assert OpenerSequence != CloserSequence

    skipper_index = sm_index.get()
    skipper_door_id = dial_db.new_door_id(skipper_index)

    opener_str, opener_comment_str = get_character_sequence(OpenerSequence)
    opener_length = len(OpenerSequence)
    closer_str, closer_comment_str = get_character_sequence(CloserSequence)
    closer_length = len(CloserSequence)

    variable_db.require("reference_p",
                        Condition="QUEX_OPTION_COLUMN_NUMBER_COUNTING")
    variable_db.require("counter")
    variable_db.require_array("Skipper%i_Opener",
                              Initial="{ %s }" % opener_str,
                              ElementN=opener_length,
                              Index=skipper_index)
    variable_db.require("Skipper%i_OpenerEnd",
                        "Skipper%i_Opener + (ptrdiff_t)%i" %
                        (skipper_index, opener_length),
                        Index=skipper_index)
    variable_db.require("Skipper%i_Opener_it", "0x0", Index=skipper_index)
    variable_db.require_array("Skipper%i_Closer",
                              Initial="{ %s }" % closer_str,
                              ElementN=closer_length,
                              Index=skipper_index)
    variable_db.require("Skipper%i_CloserEnd",
                        "Skipper%i_Closer + (ptrdiff_t)%i" %
                        (skipper_index, closer_length),
                        Index=skipper_index)
    variable_db.require("Skipper%i_Closer_it", "0x0", Index=skipper_index)

    reference_p_def = "    __QUEX_IF_COUNT_COLUMNS(reference_p = QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer));\n"
    before_reload   = "    __QUEX_IF_COUNT_COLUMNS_ADD((size_t)(QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer)\n" + \
                      "                                - reference_p));\n"
    after_reload = "        __QUEX_IF_COUNT_COLUMNS(reference_p = QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer));\n"

    if CloserSequence[-1] == ord('\n'):
        end_procedure = "       __QUEX_IF_COUNT_LINES_ADD((size_t)1);\n"
        end_procedure += "       __QUEX_IF_COUNT_COLUMNS_SET((size_t)1);\n"
    else:
        end_procedure = "        __QUEX_IF_COUNT_COLUMNS_ADD((size_t)(QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer)\n" + \
                        "                                    - reference_p));\n"

    reload_door_id = dial_db.new_door_id()
    on_skip_range_open = get_on_skip_range_open(OnSkipRangeOpen,
                                                CloserPattern,
                                                NestedF=True)

    code_str = blue_print(
        template_str,
        [
            ["$$SKIPPER_INDEX$$", __nice(skipper_index)],
            #
            ["$$OPENER_LENGTH$$", "%i" % opener_length],
            ["$$INPUT_P_INCREMENT$$",
             Lng.INPUT_P_INCREMENT()],
            ["$$INPUT_P_DECREMENT$$",
             Lng.INPUT_P_DECREMENT()],
            ["$$INPUT_GET$$", Lng.ACCESS_INPUT()],
            [
                "$$IF_INPUT_EQUAL_DELIMITER_0$$",
                Lng.IF_INPUT("==", "Skipper$$SKIPPER_INDEX$$[0]")
            ],
            ["$$ENDIF$$", Lng.END_IF()],
            ["$$ENTRY$$", Lng.LABEL(skipper_door_id)],
            ["$$RELOAD$$",
             dial_db.get_label_by_door_id(reload_door_id)],
            ["$$GOTO_AFTER_END_OF_SKIPPING$$",
             Lng.GOTO(DoorIdAfter)],
            ["$$GOTO_RELOAD$$", Lng.GOTO(reload_door_id)],
            ["$$INPUT_P_TO_LEXEME_START$$",
             Lng.INPUT_P_TO_LEXEME_START()],
            # 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_ENTRY$$", Lng.GOTO(skipper_door_id)],
            ["$$MARK_LEXEME_START$$",
             Lng.LEXEME_START_SET()],
            ["$$ON_SKIP_RANGE_OPEN$$", on_skip_range_open],
            #
            ["$$LC_COUNT_COLUMN_N_POINTER_DEFINITION$$", reference_p_def],
            ["$$LC_COUNT_IN_LOOP$$",
             line_column_counter_in_loop()],
            ["$$LC_COUNT_END_PROCEDURE$$", end_procedure],
            ["$$LC_COUNT_BEFORE_RELOAD$$", before_reload],
            ["$$LC_COUNT_AFTER_RELOAD$$", after_reload],
        ])

    return [code_str]
Exemplo n.º 10
0
def require_data(PWState, TheAnalyzer):
    """Defines the transition targets for each involved state.
    """
    LanguageDB = Setup.language_db
    variable_db.require("path_iterator")

    def __door_adr_sequences():
        result = ["{\n"]
        offset = 0
        for path_id, path in enumerate(PWState.path_list):
            # NOTE: For all states in the path the 'from_state_index, to_state_index' can
            #       be determined, **except** for the FIRST state in the path. Thus for
            #       this state the 'door' cannot be determined in case that it is
            #       "not uniform_doors_f()".
            #
            #       However, the only occasion where the FIRST state in the path may be
            #       used is reload during the FIRST state. The reload adapts the positions
            #       and acceptances are not changed. So, we can use the common entry
            #       to the first state as a reference here.
            prev_state_index = path[0][0]
            result.append("        ")
            for state_index in (x[0] for x in path[1:]):
                result.append("QUEX_LABEL(%i), " % LanguageDB.ADDRESS(state_index, prev_state_index))
                prev_state_index = state_index
            result.append("/* Zero of Elegance */0x0,")
            result.append("\n")

            offset += len(path)

        result.append("    }")
        return offset, result

    def __character_sequences():
        result = ["{\n"]
        offset = 0
        for path_id, path in enumerate(PWState.path_list):
            # Commenting the transition sequence is not dangerous. 'COMMENT' eliminates
            # comment delimiters if they would appear in the sequence_str.
            # sequence_str = imap(lambda x: Interval(x[1]).get_utf8_string(), path[:-1])
            # memory.append(LanguageDB.COMMENT("".join(sequence_str)) + "\n")
            # Last element of sequence contains only the 'end state'.
            result.append("        ")
            result.extend("%i, " % x.transition_char_to_next for x in path[:-1])
            result.append("QUEX_SETTING_PATH_TERMINATION_CODE,")
            result.append("\n")

            variable_db.require(
                "path_walker_%i_path_%i",
                Initial="path_walker_%i_path_base + %i" % (PWState.index, offset),
                Index=(PWState.index, path_id),
            )

            offset += len(path)

        result.append("    }")
        return offset, result

    # (*) Path Walker Basis
    # The 'base' must be defined before all --> PriorityF (see table in variable_db)
    element_n, character_sequence_str = __character_sequences()
    variable_db.require_array(
        "path_walker_%i_path_base", ElementN=element_n, Initial=character_sequence_str, Index=PWState.index
    )

    # (*) The State Information for each path step
    if PWState.uniform_entry_door_id_along_all_paths is None:
        element_n, state_sequence_str = __door_adr_sequences()
        variable_db.require_array(
            "path_walker_%i_state_base", ElementN=element_n, Initial=state_sequence_str, Index=PWState.index
        )
        # The path_iterator is incremented before the 'goto', thus
        # 'path_iterator - (path_base + 1)' gives actually the correct offset.
        # We define a variable for that, for elegance.
        variable_db.require(
            "path_walker_%i_reference", Initial="path_walker_%i_path_base + 1" % PWState.index, Index=(PWState.index)
        )
Exemplo n.º 11
0
def require_data(PWState, TheAnalyzer):
    """Defines the transition targets for each involved state.
    """
    
    variable_db.require("path_iterator")

    def __door_adr_sequences(PWState):
        result = ["{\n"]
        length = 0
        for path_id, door_id_sequence in enumerate(PWState.door_id_sequence_list):
            # NOTE: For all states in the path the 'from_state_index, to_state_index' can
            #       be determined, **except** for the FIRST state in the path. Thus for
            #       this state the 'door' cannot be determined in case that it is 
            #       "not uniform_doors_f()". 
            #
            #       However, the only occasion where the FIRST state in the path may be 
            #       used is reload during the FIRST state. The reload adapts the positions
            #       and acceptances are not changed. So, we can use the common entry
            #       to the first state as a reference here.
            ## print "#DoorID, Adr:", [(door_id, Lng.ADDRESS_BY_DOOR_ID(door_id)) for door_id in door_id_sequence]
            result.append("        ")
            result.append("/* Padding */0x0, ")
            result.extend("QUEX_LABEL(%i), " % dial_db.get_address_by_door_id(door_id, RoutedF=True)
                          for door_id in door_id_sequence)
            result.append("\n")

            length += len(door_id_sequence) + 1 # 1 padding element

        result.append("    }");
        return length, result

    def __character_sequences(PathList):
        result = ["{\n"]
        offset = 0
        for path_id, step_list in enumerate(PathList):
            ## Commenting the transition sequence is not dangerous. 'COMMENT' eliminates
            ## comment delimiters if they would appear in the sequence_str.
            ##   sequence_str = imap(lambda x: Interval(x[1]).get_utf8_string(), step_list[:-1])
            ##   memory.append(Lng.COMMENT("".join(sequence_str)) + "\n")

            result.append("        ")
            result.extend("%i, " % x.trigger for x in step_list[:-1])
            result.append("QUEX_SETTING_PATH_TERMINATION_CODE,")
            result.append("\n")

            offset += len(step_list)

        result.append("    }")
        return offset, result

    # (*) Path Walker Basis
    # The 'base' must be defined before all --> PriorityF (see table in variable_db)
    element_n, character_sequence_str = __character_sequences(PWState.path_list)

    offset = 0
    for path_id, step_list in enumerate(PWState.path_list):
        variable_db.require("path_walker_%i_path_%i", 
                            Initial = "&path_walker_%i_path_base[%i]" % (PWState.index, offset), 
                            Index   = (PWState.index, path_id))
        offset += len(step_list)

    variable_db.require_array("path_walker_%i_path_base", 
                              ElementN = element_n,
                              Initial  = character_sequence_str,
                              Index    = PWState.index)
    
    # (*) The State Information for each path step
    if PWState.uniform_door_id is None:
        element_n, door_adr_sequence_str = __door_adr_sequences(PWState)
        variable_db.require_array("path_walker_%i_state_base", 
                                  ElementN = element_n,
                                  Initial  = door_adr_sequence_str,
                                  Index    = PWState.index)

        # The path_iterator is incremented before the 'goto', thus
        # 'path_iterator - (path_base + 1)' gives actually the correct offset.
        # We define a variable for that, for elegance.
        variable_db.require("path_walker_%i_reference", 
                            Initial = "path_walker_%i_path_base" % PWState.index, 
                            Index   = (PWState.index))
Exemplo n.º 12
0
def require_data(PWState, TheAnalyzer):
    """Defines the transition targets for each involved state.
    """
    LanguageDB = Setup.language_db
    variable_db.require("path_iterator")

    def __door_adr_sequences():
        result = ["{\n"]
        offset = 0
        for path_id, path in enumerate(PWState.path_list):
            # NOTE: For all states in the path the 'from_state_index, to_state_index' can
            #       be determined, **except** for the FIRST state in the path. Thus for
            #       this state the 'door' cannot be determined in case that it is
            #       "not uniform_doors_f()".
            #
            #       However, the only occasion where the FIRST state in the path may be
            #       used is reload during the FIRST state. The reload adapts the positions
            #       and acceptances are not changed. So, we can use the common entry
            #       to the first state as a reference here.
            prev_state_index = path[0][0]
            result.append("        ")
            for state_index in (x[0] for x in path[1:]):
                result.append(
                    "QUEX_LABEL(%i), " %
                    LanguageDB.ADDRESS(state_index, prev_state_index))
                prev_state_index = state_index
            result.append("/* Zero of Elegance */0x0,")
            result.append("\n")

            offset += len(path)

        result.append("    }")
        return offset, result

    def __character_sequences():
        result = ["{\n"]
        offset = 0
        for path_id, path in enumerate(PWState.path_list):
            # Commenting the transition sequence is not dangerous. 'COMMENT' eliminates
            # comment delimiters if they would appear in the sequence_str.
            # sequence_str = imap(lambda x: Interval(x[1]).get_utf8_string(), path[:-1])
            # memory.append(LanguageDB.COMMENT("".join(sequence_str)) + "\n")
            # Last element of sequence contains only the 'end state'.
            result.append("        ")
            result.extend("%i, " % x.transition_char_to_next
                          for x in path[:-1])
            result.append("QUEX_SETTING_PATH_TERMINATION_CODE,")
            result.append("\n")

            variable_db.require("path_walker_%i_path_%i",
                                Initial="path_walker_%i_path_base + %i" %
                                (PWState.index, offset),
                                Index=(PWState.index, path_id))

            offset += len(path)

        result.append("    }")
        return offset, result

    # (*) Path Walker Basis
    # The 'base' must be defined before all --> PriorityF (see table in variable_db)
    element_n, character_sequence_str = __character_sequences()
    variable_db.require_array("path_walker_%i_path_base",
                              ElementN=element_n,
                              Initial=character_sequence_str,
                              Index=PWState.index)

    # (*) The State Information for each path step
    if PWState.uniform_entry_door_id_along_all_paths is None:
        element_n, state_sequence_str = __door_adr_sequences()
        variable_db.require_array("path_walker_%i_state_base",
                                  ElementN=element_n,
                                  Initial=state_sequence_str,
                                  Index=PWState.index)
        # The path_iterator is incremented before the 'goto', thus
        # 'path_iterator - (path_base + 1)' gives actually the correct offset.
        # We define a variable for that, for elegance.
        variable_db.require("path_walker_%i_reference",
                            Initial="path_walker_%i_path_base + 1" %
                            PWState.index,
                            Index=(PWState.index))
Exemplo n.º 13
0
def get_skipper(EndSequence, CloserPattern, ModeName, OnSkipRangeOpen, DoorIdAfter):
    assert len(EndSequence) >= 1

    global template_str

    # Name the $$SKIPPER$$
    skipper_index   = sm_index.get()
    skipper_door_id = dial_db.new_door_id(skipper_index)

    delimiter_str, delimiter_comment_str = get_character_sequence(EndSequence)

    end_sequence_transformed = transformation.do_sequence(EndSequence)

    # Determine the $$DELIMITER$$
    delimiter_length = len(end_sequence_transformed)

    delimiter_comment_str = Lng.COMMENT("                         Delimiter: %s" % delimiter_comment_str)

    # Determine the check for the tail of the delimiter
    delimiter_remainder_test_str = ""
    if len(EndSequence) != 1: 
        txt = "".join(
            "    %s" % Lng.IF_GOTO(Lng.INPUT_P_DEREFERENCE(i-1), "!=", 
                                   "Skipper$$SKIPPER_INDEX$$[%i]" % i,
                                   skipper_door_id, i == 1)
            for i, letter in enumerate(EndSequence[1:], start=1)
        )
        delimiter_remainder_test_str = txt

    door_id_reload = dial_db.new_door_id()
    on_skip_range_open = get_on_skip_range_open(OnSkipRangeOpen, CloserPattern)

    # The main part
    code_str = blue_print(template_str,
                          [
                           ["$$DELIMITER_COMMENT$$",              delimiter_comment_str],
                           ["$$INPUT_P_INCREMENT$$",              Lng.INPUT_P_INCREMENT()],
                           ["$$INPUT_P_DECREMENT$$",              Lng.INPUT_P_DECREMENT()],
                           ["$$INPUT_GET$$",                      Lng.ACCESS_INPUT()],
                           ["$$IF_INPUT_EQUAL_DELIMITER_0$$",     Lng.IF_INPUT("==", "Skipper$$SKIPPER_INDEX$$[0]")],
                           ["$$ENDIF$$",                          Lng.END_IF()],
                           ["$$ENTRY$$",                          dial_db.get_label_by_door_id(skipper_door_id)],
                           ["$$RELOAD$$",                         dial_db.get_label_by_door_id(door_id_reload)],
                           ["$$GOTO_ENTRY$$",                     Lng.GOTO(skipper_door_id)],
                           ["$$INPUT_P_TO_LEXEME_START$$",        Lng.INPUT_P_TO_LEXEME_START()],
                           # 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_AFTER_END_OF_SKIPPING$$",     Lng.GOTO(DoorIdAfter)], 
                           ["$$MARK_LEXEME_START$$",              Lng.LEXEME_START_SET()],
                           ["$$DELIMITER_REMAINDER_TEST$$",       delimiter_remainder_test_str],
                           ["$$ON_SKIP_RANGE_OPEN$$",             on_skip_range_open],
                          ])

    # Line and column number counting
    code_str, reference_p_f = __lc_counting_replacements(code_str, EndSequence)

    # The finishing touch
    code_str = blue_print(code_str,
                          [["$$SKIPPER_INDEX$$", __nice(skipper_index)],
                           ["$$GOTO_RELOAD$$",   Lng.GOTO(door_id_reload)]])

    if reference_p_f:
        variable_db.require("reference_p", Condition="QUEX_OPTION_COLUMN_NUMBER_COUNTING")

    variable_db.require_array("Skipper%i", Initial="{ %s }" % delimiter_str, ElementN=delimiter_length, Index=skipper_index)
    variable_db.require("Skipper%iL", "%i" % delimiter_length, Index=skipper_index)
    variable_db.require("text_end")

    variable_db.require("input") 

    return [ code_str ]
Exemplo n.º 14
0
def require_data(PWState, TheAnalyzer):
    """Defines the transition targets for each involved state.
    """

    variable_db.require("path_iterator")

    def __door_adr_sequences(PWState):
        result = ["{\n"]
        length = 0
        for path_id, door_id_sequence in enumerate(
                PWState.door_id_sequence_list):
            # NOTE: For all states in the path the 'from_state_index, to_state_index' can
            #       be determined, **except** for the FIRST state in the path. Thus for
            #       this state the 'door' cannot be determined in case that it is
            #       "not uniform_doors_f()".
            #
            #       However, the only occasion where the FIRST state in the path may be
            #       used is reload during the FIRST state. The reload adapts the positions
            #       and acceptances are not changed. So, we can use the common entry
            #       to the first state as a reference here.
            ## print "#DoorID, Adr:", [(door_id, Lng.ADDRESS_BY_DOOR_ID(door_id)) for door_id in door_id_sequence]
            result.append("        ")
            result.append("/* Padding */0x0, ")
            result.extend("QUEX_LABEL(%i), " %
                          dial_db.get_address_by_door_id(door_id, RoutedF=True)
                          for door_id in door_id_sequence)
            result.append("\n")

            length += len(door_id_sequence) + 1  # 1 padding element

        result.append("    }")
        return length, result

    def __character_sequences(PathList):
        result = ["{\n"]
        offset = 0
        for path_id, step_list in enumerate(PathList):
            ## Commenting the transition sequence is not dangerous. 'COMMENT' eliminates
            ## comment delimiters if they would appear in the sequence_str.
            ##   sequence_str = imap(lambda x: Interval(x[1]).get_utf8_string(), step_list[:-1])
            ##   memory.append(Lng.COMMENT("".join(sequence_str)) + "\n")

            result.append("        ")
            result.extend("%i, " % x.trigger for x in step_list[:-1])
            result.append("QUEX_SETTING_PATH_TERMINATION_CODE,")
            result.append("\n")

            offset += len(step_list)

        result.append("    }")
        return offset, result

    # (*) Path Walker Basis
    # The 'base' must be defined before all --> PriorityF (see table in variable_db)
    element_n, character_sequence_str = __character_sequences(
        PWState.path_list)

    offset = 0
    for path_id, step_list in enumerate(PWState.path_list):
        variable_db.require("path_walker_%i_path_%i",
                            Initial="&path_walker_%i_path_base[%i]" %
                            (PWState.index, offset),
                            Index=(PWState.index, path_id))
        offset += len(step_list)

    variable_db.require_array("path_walker_%i_path_base",
                              ElementN=element_n,
                              Initial=character_sequence_str,
                              Index=PWState.index)

    # (*) The State Information for each path step
    if PWState.uniform_door_id is None:
        element_n, door_adr_sequence_str = __door_adr_sequences(PWState)
        variable_db.require_array("path_walker_%i_state_base",
                                  ElementN=element_n,
                                  Initial=door_adr_sequence_str,
                                  Index=PWState.index)

        # The path_iterator is incremented before the 'goto', thus
        # 'path_iterator - (path_base + 1)' gives actually the correct offset.
        # We define a variable for that, for elegance.
        variable_db.require("path_walker_%i_reference",
                            Initial="path_walker_%i_path_base" % PWState.index,
                            Index=(PWState.index))