示例#1
0
def backward_lexing(OriginList):
    """Backward Lexing:
       -- Using an inverse state machine from 'real' current start position backwards
          until a drop out occurs.
       -- During backward lexing, there is no 'winner' so all origins that indicate
          acceptance need to be considered. They raise there flag 'pre-condition fulfilled'.
    """
    LanguageDB = Setup.language_db

    # There should be nothing, but unconditional acceptances or no-acceptance 
    # origins in the list of origins.
    inadmissible_origin_list = filter(lambda origin:
                                      origin.pre_context_begin_of_line_f() or
                                      origin.pre_context_id() != -1L or
                                      origin.post_context_id() != -1L,
                                      OriginList)
    assert inadmissible_origin_list == [], \
           "Inadmissible origins for inverse state machine."
    #___________________________________________________________________________________________

    txt = []
    for origin in OriginList:
        if not origin.store_input_position_f(): continue
        assert origin.is_acceptance()
        variable = "pre_context_%s_fulfilled_f" % __nice(origin.state_machine_id)
        txt.append("    " + LanguageDB["$assignment"](variable, 1))
        txt.append("    __quex_debug(\"pre context %s fulfilled\");\n" % __nice(origin.state_machine_id));
    txt.append("\n")

    return txt
示例#2
0
def backward_lexing(OriginList):
    """Backward Lexing:
       -- Using an inverse state machine from 'real' current start position backwards
          until a drop out occurs.
       -- During backward lexing, there is no 'winner' so all origins that indicate
          acceptance need to be considered. They raise there flag 'pre-condition fulfilled'.
    """
    LanguageDB = Setup.language_db

    # There should be nothing, but unconditional acceptances or no-acceptance
    # origins in the list of origins.
    inadmissible_origin_list = filter(
        lambda origin: origin.pre_context_begin_of_line_f() or origin.
        pre_context_id() != -1L or origin.post_context_id() != -1L, OriginList)
    assert inadmissible_origin_list == [], \
           "Inadmissible origins for inverse state machine."
    #___________________________________________________________________________________________

    txt = []
    for origin in OriginList:
        if not origin.store_input_position_f(): continue
        assert origin.is_acceptance()
        variable = "pre_context_%s_fulfilled_f" % __nice(
            origin.state_machine_id)
        txt.append("    " + LanguageDB["$assignment"](variable, 1))
        txt.append("    __quex_debug(\"pre context %s fulfilled\");\n" %
                   __nice(origin.state_machine_id))
    txt.append("\n")

    return txt
示例#3
0
def __handle_post_conditioned_core_patterns(OriginList, SMD):
    """Creates code to store the input position for post conditioned
       core patterns. That means, that the input pointer must return
       to this place in case that the post condition is fulfilled.
    """
    global LanguageDB

    # (1) Set the post context registers (if appropriate)
    #     (also determine the list of acceptance origins)
    txtl = []
    for origin in OriginList:
        if origin.is_end_of_post_contexted_core_pattern():
            # Assumption about origin based on assumption about single pattern state machine:
            #
            #    According to 'setup_post_context.py' (currently line 121) no acceptance
            #    state of a post context can store the input position. This has been made
            #    impossible! Otherwise, the post context would have zero length.
            #
            #    Post-conditions via backward search, i.e. pseudo ambigous post conditions,
            #    are a different ball-game.
            #
            assert origin.is_acceptance() == False

            # Store current input position, to be restored when post condition really matches
            post_context_index = SMD.get_post_context_index(
                origin.state_machine_id)
            txtl += [
                    "    __quex_debug(\"post context %s: mark position\");\n" % __nice(origin.state_machine_id),
                    "    " + LanguageDB["$input/tell_position"]("post_context_start_position[%i]" % \
                             post_context_index),
                    "\n"
                    ]

    return txtl
示例#4
0
def __handle_post_conditioned_core_patterns(OriginList, SMD):
    """Creates code to store the input position for post conditioned
       core patterns. That means, that the input pointer must return
       to this place in case that the post condition is fulfilled.
    """
    global LanguageDB

    # (1) Set the post context registers (if appropriate)
    #     (also determine the list of acceptance origins)
    txtl = []
    for origin in OriginList: 
        if origin.is_end_of_post_contexted_core_pattern():
            # Assumption about origin based on assumption about single pattern state machine:
            #
            #    According to 'setup_post_context.py' (currently line 121) no acceptance
            #    state of a post context can store the input position. This has been made 
            #    impossible! Otherwise, the post context would have zero length.
            #
            #    Post-conditions via backward search, i.e. pseudo ambigous post conditions,
            #    are a different ball-game.
            #
            assert origin.is_acceptance() == False

            # Store current input position, to be restored when post condition really matches
            post_context_index = SMD.get_post_context_index(origin.state_machine_id)
            txtl += [
                    "    __quex_debug(\"post context %s: mark position\");\n" % __nice(origin.state_machine_id),
                    "    " + LanguageDB["$input/tell_position"]("post_context_start_position[%i]" % \
                             post_context_index),
                    "\n"
                    ]

    return txtl
示例#5
0
文件: range.py 项目: jirkamarsik/quex
def get_skipper(EndSequence, Mode=None, IndentationCounterTerminalID=None, OnSkipRangeOpenStr=""):
    assert type(EndSequence) == list
    assert len(EndSequence) >= 1
    assert map(type, EndSequence) == [int] * len(EndSequence)

    local_variable_db = {}

    global template_str

    LanguageDB   = Setup.language_db

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

    # Determine the $$DELIMITER$$
    delimiter_str,        \
    delimiter_length_str, \
    delimiter_comment_str \
                          = get_character_sequence(EndSequence)

    delimiter_comment_str  = LanguageDB["$comment"]("                         Delimiter: " 
                                                    + delimiter_comment_str)

    # Determine the check for the tail of the delimiter
    delimiter_remainder_test_str = ""
    if len(EndSequence) != 1: 
        txt = ""
        i = 0
        for letter in EndSequence[1:]:
            i += 1
            txt += "    " + LanguageDB["$input/get-offset"](i-1) + "\n"
            txt += "    " + LanguageDB["$if !="]("Skipper$$SKIPPER_INDEX$$[%i]" % i)
            txt += "         goto %s;" % get_label("$entry", skipper_index, U=True) 
            txt += "    " + LanguageDB["$endif"]
        delimiter_remainder_test_str = txt

    if not end_delimiter_is_subset_of_indentation_counter_newline(Mode, EndSequence):
        goto_after_end_of_skipping_str = "goto %s;" % get_label("$start", U=True)
    else:
        # If there is indentation counting involved, then the counter's terminal id must
        # be determined at this place.
        assert IndentationCounterTerminalID != None
        # If the ending delimiter is a subset of what the 'newline' pattern triggers 
        # in indentation counting => move on to the indentation counter.
        goto_after_end_of_skipping_str = "goto %s;" % get_label("$terminal-direct", IndentationCounterTerminalID, U=True)

    if OnSkipRangeOpenStr != "": on_skip_range_open_str = OnSkipRangeOpenStr
    else:                        on_skip_range_open_str = get_on_skip_range_open(Mode, EndSequence)

    # The main part
    code_str = blue_print(template_str,
                          [["$$DELIMITER$$",                      delimiter_str],
                           ["$$DELIMITER_LENGTH$$",               delimiter_length_str],
                           ["$$DELIMITER_COMMENT$$",              delimiter_comment_str],
                           ["$$WHILE_1_PLUS_1_EQUAL_2$$",         LanguageDB["$loop-start-endless"]],
                           ["$$END_WHILE$$",                      LanguageDB["$loop-end"]],
                           ["$$INPUT_P_INCREMENT$$",              LanguageDB["$input/increment"]],
                           ["$$INPUT_P_DECREMENT$$",              LanguageDB["$input/decrement"]],
                           ["$$INPUT_GET$$",                      LanguageDB["$input/get"]],
                           ["$$IF_INPUT_EQUAL_DELIMITER_0$$",     LanguageDB["$if =="]("Skipper$$SKIPPER_INDEX$$[0]")],
                           ["$$ENDIF$$",                          LanguageDB["$endif"]],
                           ["$$ENTRY$$",                          get_label("$entry", skipper_index)],
                           ["$$RELOAD$$",                         get_label("$reload", skipper_index)],
                           ["$$GOTO_ENTRY$$",                     get_label("$entry", skipper_index, U=True)],
                           # 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$$",     goto_after_end_of_skipping_str], 
                           ["$$MARK_LEXEME_START$$",              LanguageDB["$mark-lexeme-start"]],
                           ["$$DELIMITER_REMAINDER_TEST$$",       delimiter_remainder_test_str],
                           ["$$ON_SKIP_RANGE_OPEN$$",             on_skip_range_open_str],
                          ])

    # 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$$",   get_label("$reload", skipper_index)]])

    if reference_p_f:
        local_variable_db["QUEX_OPTION_COLUMN_NUMBER_COUNTING/reference_p"] = \
                           Variable("reference_p", 
                                    "QUEX_TYPE_CHARACTER_POSITION", 
                                    None,
                                    "(QUEX_TYPE_CHARACTER_POSITION)0x0",
                                    "QUEX_OPTION_COLUMN_NUMBER_COUNTING")

    return code_str, local_variable_db
示例#6
0
文件: range.py 项目: jirkamarsik/quex
def get_skipper(EndSequence, Mode=None, IndentationCounterTerminalID=None, OnSkipRangeOpenStr=""):
    assert type(EndSequence) == list
    assert len(EndSequence) >= 1
    assert map(type, EndSequence) == [int] * len(EndSequence)

    local_variable_db = {}

    global template_str

    LanguageDB = Setup.language_db

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

    # Determine the $$DELIMITER$$
    delimiter_str, delimiter_length_str, delimiter_comment_str = get_character_sequence(EndSequence)

    delimiter_comment_str = LanguageDB["$comment"]("                         Delimiter: " + delimiter_comment_str)

    # Determine the check for the tail of the delimiter
    delimiter_remainder_test_str = ""
    if len(EndSequence) != 1:
        txt = ""
        i = 0
        for letter in EndSequence[1:]:
            i += 1
            txt += "    " + LanguageDB["$input/get-offset"](i - 1) + "\n"
            txt += "    " + LanguageDB["$if !="]("Skipper$$SKIPPER_INDEX$$[%i]" % i)
            txt += "         goto %s;" % get_label("$entry", skipper_index, U=True)
            txt += "    " + LanguageDB["$endif"]
        delimiter_remainder_test_str = txt

    if not end_delimiter_is_subset_of_indentation_counter_newline(Mode, EndSequence):
        goto_after_end_of_skipping_str = "goto %s;" % get_label("$start", U=True)
    else:
        # If there is indentation counting involved, then the counter's terminal id must
        # be determined at this place.
        assert IndentationCounterTerminalID != None
        # If the ending delimiter is a subset of what the 'newline' pattern triggers
        # in indentation counting => move on to the indentation counter.
        goto_after_end_of_skipping_str = "goto %s;" % get_label(
            "$terminal-direct", IndentationCounterTerminalID, U=True
        )

    if OnSkipRangeOpenStr != "":
        on_skip_range_open_str = OnSkipRangeOpenStr
    else:
        on_skip_range_open_str = get_on_skip_range_open(Mode, EndSequence)

    # The main part
    code_str = blue_print(
        template_str,
        [
            ["$$DELIMITER$$", delimiter_str],
            ["$$DELIMITER_LENGTH$$", delimiter_length_str],
            ["$$DELIMITER_COMMENT$$", delimiter_comment_str],
            ["$$WHILE_1_PLUS_1_EQUAL_2$$", LanguageDB["$loop-start-endless"]],
            ["$$END_WHILE$$", LanguageDB["$loop-end"]],
            ["$$INPUT_P_INCREMENT$$", LanguageDB["$input/increment"]],
            ["$$INPUT_P_DECREMENT$$", LanguageDB["$input/decrement"]],
            ["$$INPUT_GET$$", LanguageDB["$input/get"]],
            ["$$IF_INPUT_EQUAL_DELIMITER_0$$", LanguageDB["$if =="]("Skipper$$SKIPPER_INDEX$$[0]")],
            ["$$ENDIF$$", LanguageDB["$endif"]],
            ["$$ENTRY$$", get_label("$entry", skipper_index)],
            ["$$RELOAD$$", get_label("$reload", skipper_index)],
            ["$$GOTO_ENTRY$$", get_label("$entry", skipper_index, U=True)],
            # 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$$", goto_after_end_of_skipping_str],
            ["$$MARK_LEXEME_START$$", LanguageDB["$mark-lexeme-start"]],
            ["$$DELIMITER_REMAINDER_TEST$$", delimiter_remainder_test_str],
            ["$$ON_SKIP_RANGE_OPEN$$", on_skip_range_open_str],
        ],
    )

    # 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$$", get_label("$reload", skipper_index)]],
    )

    if reference_p_f:
        local_variable_db["QUEX_OPTION_COLUMN_NUMBER_COUNTING/reference_p"] = Variable(
            "reference_p",
            "QUEX_TYPE_CHARACTER_POSITION",
            None,
            "(QUEX_TYPE_CHARACTER_POSITION)0x0",
            "QUEX_OPTION_COLUMN_NUMBER_COUNTING",
        )

    return code_str, local_variable_db
示例#7
0
def get_skipper(OpenerSequence, CloserSequence, Mode=None, IndentationCounterTerminalID=None, OnSkipRangeOpenStr=""):
    assert OpenerSequence.__class__  == list
    assert len(OpenerSequence)       >= 1
    assert map(type, OpenerSequence) == [int] * len(OpenerSequence)
    assert CloserSequence.__class__  == list
    assert len(CloserSequence)       >= 1
    assert map(type, CloserSequence) == [int] * len(CloserSequence)
    assert OpenerSequence != CloserSequence

    LanguageDB    = Setup.language_db

    skipper_index = sm_index.get()

    opener_str, opener_length_str, opener_comment_str = get_character_sequence(OpenerSequence)
    closer_str, closer_length_str, closer_comment_str = get_character_sequence(CloserSequence)

    if not end_delimiter_is_subset_of_indentation_counter_newline(Mode, CloserSequence):
        goto_after_end_of_skipping_str = "goto %s;" % get_label("$start", U=True)
    else:
        # If there is indentation counting involved, then the counter's terminal id must
        # be determined at this place.
        assert IndentationCounterTerminalID != None
        # If the ending delimiter is a subset of what the 'newline' pattern triggers 
        # in indentation counting => move on to the indentation counter.
        goto_after_end_of_skipping_str = "goto %s;" % get_label("$terminal-direct", 
                                                                IndentationCounterTerminalID, U=True)

    if OnSkipRangeOpenStr != "": on_skip_range_open_str = OnSkipRangeOpenStr
    else:                        on_skip_range_open_str = get_on_skip_range_open(Mode, CloserSequence)

    local_variable_db = { 
        "counter":     Variable("counter", "size_t", None, "0"),
        "QUEX_OPTION_COLUMN_NUMBER_COUNTING/reference_p": 
                       Variable("reference_p", 
                                "QUEX_TYPE_CHARACTER_POSITION", 
                                None,
                                "(QUEX_TYPE_CHARACTER_POSITION)0x0", 
                                "QUEX_OPTION_COLUMN_NUMBER_COUNTING")
    }
    reference_p_def = "    __QUEX_IF_COUNT_COLUMNS(reference_p = QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer));\n"

    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" 

    code_str = blue_print(template_str,
                          [
                           ["$$SKIPPER_INDEX$$",   __nice(skipper_index)],
                           #
                           ["$$OPENER$$",          opener_str],
                           ["$$OPENER_LENGTH$$",   opener_length_str],
                           ["$$OPENER_COMMENT$$",  opener_comment_str],
                           ["$$CLOSER$$",          closer_str],
                           ["$$CLOSER_LENGTH$$",   closer_length_str],
                           ["$$CLOSER_COMMENT$$",  closer_comment_str],
                           # 
                           ["$$INPUT_P_INCREMENT$$",              LanguageDB["$input/increment"]],
                           ["$$INPUT_P_DECREMENT$$",              LanguageDB["$input/decrement"]],
                           ["$$INPUT_GET$$",                      LanguageDB["$input/get"]],
                           ["$$IF_INPUT_EQUAL_DELIMITER_0$$",     LanguageDB["$if =="]("Skipper$$SKIPPER_INDEX$$[0]")],
                           ["$$ENDIF$$",                          LanguageDB["$endif"]],
                           ["$$ENTRY$$",                          get_label("$entry", skipper_index)],
                           ["$$RELOAD$$",                         get_label("$reload", skipper_index)],
                           ["$$GOTO_AFTER_END_OF_SKIPPING$$",     goto_after_end_of_skipping_str], 
                           ["$$GOTO_RELOAD$$",                    get_label("$reload", skipper_index)],
                           # 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$$",                     get_label("$entry", skipper_index)],
                           ["$$MARK_LEXEME_START$$",              LanguageDB["$mark-lexeme-start"]],
                           ["$$ON_SKIP_RANGE_OPEN$$",             on_skip_range_open_str],
                           #
                           ["$$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, local_variable_db
示例#8
0
def get_skipper(OpenerSequence,
                CloserSequence,
                Mode=None,
                IndentationCounterTerminalID=None,
                OnSkipRangeOpenStr=""):
    assert OpenerSequence.__class__ == list
    assert len(OpenerSequence) >= 1
    assert map(type, OpenerSequence) == [int] * len(OpenerSequence)
    assert CloserSequence.__class__ == list
    assert len(CloserSequence) >= 1
    assert map(type, CloserSequence) == [int] * len(CloserSequence)
    assert OpenerSequence != CloserSequence

    LanguageDB = Setup.language_db

    skipper_index = sm_index.get()

    opener_str, opener_length_str, opener_comment_str = get_character_sequence(
        OpenerSequence)
    closer_str, closer_length_str, closer_comment_str = get_character_sequence(
        CloserSequence)

    if not end_delimiter_is_subset_of_indentation_counter_newline(
            Mode, CloserSequence):
        goto_after_end_of_skipping_str = "goto %s;" % get_label("$start",
                                                                U=True)
    else:
        # If there is indentation counting involved, then the counter's terminal id must
        # be determined at this place.
        assert IndentationCounterTerminalID != None
        # If the ending delimiter is a subset of what the 'newline' pattern triggers
        # in indentation counting => move on to the indentation counter.
        goto_after_end_of_skipping_str = "goto %s;" % get_label(
            "$terminal-direct", IndentationCounterTerminalID, U=True)

    if OnSkipRangeOpenStr != "": on_skip_range_open_str = OnSkipRangeOpenStr
    else: on_skip_range_open_str = get_on_skip_range_open(Mode, CloserSequence)

    local_variable_db = {
        "counter":
        Variable("counter", "size_t", None, "0"),
        "QUEX_OPTION_COLUMN_NUMBER_COUNTING/reference_p":
        Variable("reference_p", "QUEX_TYPE_CHARACTER_POSITION", None,
                 "(QUEX_TYPE_CHARACTER_POSITION)0x0",
                 "QUEX_OPTION_COLUMN_NUMBER_COUNTING")
    }
    reference_p_def = "    __QUEX_IF_COUNT_COLUMNS(reference_p = QUEX_NAME(Buffer_tell_memory_adr)(&me->buffer));\n"

    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"

    code_str = blue_print(
        template_str,
        [
            ["$$SKIPPER_INDEX$$", __nice(skipper_index)],
            #
            ["$$OPENER$$", opener_str],
            ["$$OPENER_LENGTH$$", opener_length_str],
            ["$$OPENER_COMMENT$$", opener_comment_str],
            ["$$CLOSER$$", closer_str],
            ["$$CLOSER_LENGTH$$", closer_length_str],
            ["$$CLOSER_COMMENT$$", closer_comment_str],
            #
            ["$$INPUT_P_INCREMENT$$", LanguageDB["$input/increment"]],
            ["$$INPUT_P_DECREMENT$$", LanguageDB["$input/decrement"]],
            ["$$INPUT_GET$$", LanguageDB["$input/get"]],
            [
                "$$IF_INPUT_EQUAL_DELIMITER_0$$",
                LanguageDB["$if =="]("Skipper$$SKIPPER_INDEX$$[0]")
            ],
            ["$$ENDIF$$", LanguageDB["$endif"]],
            ["$$ENTRY$$", get_label("$entry", skipper_index)],
            ["$$RELOAD$$", get_label("$reload", skipper_index)],
            ["$$GOTO_AFTER_END_OF_SKIPPING$$", goto_after_end_of_skipping_str],
            ["$$GOTO_RELOAD$$",
             get_label("$reload", skipper_index)],
            # 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$$",
             get_label("$entry", skipper_index)],
            ["$$MARK_LEXEME_START$$", LanguageDB["$mark-lexeme-start"]],
            ["$$ON_SKIP_RANGE_OPEN$$", on_skip_range_open_str],
            #
            ["$$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, local_variable_db