예제 #1
0
        def __bracket(conversion_list, CallerRangeIndex):
            txt = ""
            L = len(conversion_list)
            if L == 1:
                txt += self.get_unicode_range_conversion(conversion_list[0])
                # The caller does have to implement an 'encoder
                if CallerRangeIndex != conversion_list[
                        0].byte_format_range_index:
                    txt += self.get_byte_formatter(
                        conversion_list[0].byte_format_range_index)
            else:
                # Determine whether all sub-ranges belong to the same utf8-range
                range_index = self.same_byte_format_range(conversion_list)

                # Bracket interval in the middle
                mid_index = int(float(L) / 2)
                Middle = "0x%06X" % conversion_list[
                    mid_index].codec_interval_begin
                txt += Lng.IF_INPUT("<", Middle)
                if range_index != -1:
                    # If there is no 'unicode coversion' and all ranges belong to the
                    # same byte formatting, then there is no need to bracket further:
                    if not __rely_on_ucs4_conversion_f:
                        txt += __bracket(conversion_list[:mid_index],
                                         range_index)
                        txt += Lng.ELSE + "\n"
                        txt += __bracket(conversion_list[mid_index:],
                                         range_index)
                        txt += Lng.END_IF()
                    if CallerRangeIndex != range_index:
                        txt += self.get_byte_formatter(range_index)
                else:
                    txt += __bracket(conversion_list[:mid_index], range_index)
                    txt += Lng.ELSE + "\n"
                    txt += __bracket(conversion_list[mid_index:], range_index)
                    txt += Lng.END_IF()

            if len(txt) != 0 and txt[-1] == "\n": txt = txt[:-1]
            return "    " + txt.replace("\n", "\n    ") + "\n"
예제 #2
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]
예제 #3
0
def TRY_terminal_delimiter_sequence(Mode, UnicodeSequence,
                                    UnicodeEndSequencePattern,
                                    UponReloadDoneAdr):
    UnicodeEndSequencePattern.prepare_count_info(Mode.counter_db,
                                                 Setup.buffer_codec)

    # Trasform letter by letter.
    sequence = flatten_list_of_lists(
        transformation.do_character(x, Setup.buffer_codec)
        for x in UnicodeSequence)

    EndSequenceChunkN = len(sequence)

    # Column and line number count for closing delimiter
    run_time_counting_required_f, counter_txt = \
            counter_for_pattern.get(UnicodeEndSequencePattern, ShiftF=False)
    # The Closer Delimiter must be a string. As such it has a pre-determined size.
    assert not run_time_counting_required_f

    # Column and line number count for 'normal' character.
    tm, column_counter_per_chunk = \
            counter.get_XXX_counter_map(Mode.counter_db, "me->buffer._input_p",
                                    Trafo=Setup.buffer_codec)

    dummy, character_count_txt, dummy = \
            counter.get_core_step(tm, "me->buffer._input_p")

    txt = []
    for i, x in enumerate(sequence):
        txt.append(i)
        txt.append(Lng.IF_INPUT("==", "0x%X" % x,
                                FirstF=True))  # Opening the 'if'
        txt.append(i + 1)
        txt.append("%s\n" % Lng.INPUT_P_INCREMENT())

    Lng.INDENT(counter_txt, i + 1)
    if column_counter_per_chunk:
        txt.append(i + 1)
        if column_counter_per_chunk == UnicodeEndSequencePattern.count_info(
        ).column_n_increment_by_lexeme_length:
            txt += Lng.REEFERENCE_P_COLUMN_ADD("me->buffer._input_p",
                                               column_counter_per_chunk)
        else:
            txt += Lng.REEFERENCE_P_COLUMN_ADD(
                "(me->buffer._input_p - %i)" % EndSequenceChunkN,
                column_counter_per_chunk)
            txt.append(i + 1)
            txt.extend(counter_txt)
    txt.append(i + 1)
    txt.append("break;\n")

    for i, x in r_enumerate(sequence):
        txt.append(i)
        txt.append("%s" % Lng.IF_INPUT(
            "==", "0x%X" % Setup.buffer_limit_code, FirstF=False))  # Check BLC
        txt.append(i + 1)
        txt.append("%s\n" %
                   Lng.LEXEME_START_SET("me->buffer._input_p - %i" % i))
        txt.append(i + 1)
        txt.append(
            "%s\n" %
            Lng.GOTO_RELOAD(UponReloadDoneAdr, True, engine.FORWARD))  # Reload
        if i == 0: break
        txt.append(i)
        txt.append("%s" % Lng.ELSE)
        txt.append(i + 1)
        txt.append("%s\n" % Lng.INPUT_P_ADD(-i))
        txt.append(i)
        txt.append("%s\n" % Lng.END_IF())

    txt.append(i)
    txt.append("%s\n" % Lng.END_IF())

    txt.extend(character_count_txt)

    # print "##DEBUG:\n%s" % "".join(Lng.GET_PLAIN_STRINGS(txt))
    return txt
예제 #4
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]
예제 #5
0
def framework(txt, PWState, TheAnalyzer):
    """Implement the Pathwalker's framework. The scheme for a path-walker
       is the following:

           Pathwalker Head:

              Compares the current 'input' character if it is still
              on the path or not. If it is on the path we increment
              the 'path_iterator' and re-enter the path walker. If
              not, then the thread of control enters the transition
              map.

           Pathwalker Transition Map:

             The transition map is the common transition map that all
             implemented states had in common. Now, transitions to 
             states outside the path may happen.
    """
    # Three Versions of PathWalker Heads:
    if PWState.uniform_door_id is not None:
        # UNIFORM PATHS: Along the path, always the same (or no) commands are executed.
        #
        # PathWalker Head Implementation:
        #
        #        if input == *path_iterator:
        #           path_iterator += 1
        #           if *path_iterator != TerminationCode: goto CommonPathWalkerDoor
        #           else:                                 goto TerminalDoor
        #
        # -- "goto CommonPathWalkerDoor"
        goto_next_door = "            %s\n" % Lng.GOTO(PWState.uniform_door_id)

        # -- "goto TerminalDoor"
        if PWState.uniform_terminal_door_id is not None:
            # All path have same terminal state and enter it at the same door
            goto_terminal_door = "            %s\n" % Lng.GOTO(
                PWState.uniform_terminal_door_id)
        else:
            # The terminals of the paths are different
            #
            # The "goto TerminalDoor" is implemented for each path. The single
            # goto is split into a sequence:
            #
            #      if      path_iterator == path_0_end:  goto TerminalDoorOfPath0
            #      else if path_iterator == path_1_end:  goto TerminalDoorOfPath1
            #      else if path_iterator == path_2_end:  goto TerminalDoorOfPath2
            #      ...
            tmp = ""
            offset = 0
            for path_id, door_id_sequence in enumerate(
                    PWState.door_id_sequence_list):
                offset += len(door_id_sequence) + 1
                tmp +=  "            %s"  % Lng.IF("path_iterator", "==", "&path_walker_%i_path_base[%s]" %  \
                                                          (PWState.index, offset - 1), FirstF=(path_id == 0))                                  \
                      + "                %s\n" % Lng.GOTO(door_id_sequence[-1])
            tmp += "            %s" % Lng.ELSE
            tmp += "                %s\n" % Lng.UNREACHABLE
            tmp += "            %s\n" % Lng.END_IF()
            goto_terminal_door = tmp

        path_walker_head = \
            ["    %s"            % Lng.IF_INPUT("==", "*path_iterator"),
             "        %s\n"      % Lng.PATH_ITERATOR_INCREMENT,
             "        %s"        % Lng.IF("*path_iterator", "!=", "QUEX_SETTING_PATH_TERMINATION_CODE"),
             goto_next_door,
             "        %s"        % Lng.ELSE,
             goto_terminal_door,
             "        %s\n"      % Lng.END_IF(),
             "    %s\n"          % Lng.END_IF()]
    else:
        # NON UNIFORM PATHS
        #
        # PathWalker Head Implementation:
        #
        #     if input == *path_iterator:
        #        path_iterator += 1
        #        goto NextDoor(path_iterator)
        #
        # Here, the "goto TerminalDoor" results from NextDoor(path_iterator)
        # automatically, when the path_iterator stands on the last element.
        #
        label          = "path_walker_%i_state_base[path_iterator - path_walker_%i_reference]" \
                         % (PWState.index, PWState.index)
        goto_next_door = "%s" % (Lng.GOTO_BY_VARIABLE(label))

        path_walker_head = [
            "    %s" % Lng.IF_INPUT("==", "*path_iterator"),
            "        %s\n" % Lng.PATH_ITERATOR_INCREMENT,
            "        %s\n" % goto_next_door,
            "    %s\n" % Lng.END_IF()
        ]

    txt.extend(path_walker_head)
    return