Beispiel #1
0
def _get_pre_context_epilog_definition(dial_db):
    backup_position = Lng.REGISTER_NAME(E_R.BackupStreamPositionOfLexemeStartP)

    txt = [
        Lng.LABEL(DoorID.global_end_of_pre_context_check(dial_db)),
        #-------------------
        Lng.IF(backup_position, "!=", "((QUEX_TYPE_STREAM_POSITION)-1)"),
            # "QUEX_NAME(Buffer_print_content)(&me->buffer);\n",
            # "std::cout << std::endl;\n",
            Lng.IF("false", "==", Lng.BUFFER_SEEK(backup_position)),
                Lng.RAISE_ERROR_FLAG("E_Error_File_SeekFailed"),
                Lng.RETURN,
            Lng.END_IF,
            Lng.LEXEME_START_SET(PositionStorage=None), # use '_read_p'
            # "std::cout << \"lexst \" << me->buffer._lexeme_start_p[0] << std::endl;",
            # "std::cout << \"readp \" << me->buffer._read_p[0] << std::endl;",
            # "QUEX_NAME(Buffer_print_content)(&me->buffer);\n",
            # "std::cout << std::endl;\n",
            Lng.ASSIGN(backup_position, "((QUEX_TYPE_STREAM_POSITION)-1)"),
        Lng.ELSE_FOLLOWS,
            #-----------------------
            # -- set the input stream back to the real current position.
            #    during backward lexing the analyzer went backwards, so it needs to be reset.
            Lng.INPUT_P_TO_LEXEME_START(),
        Lng.END_IF,
    ]

    return [ "%s\n" % line for line in txt ]
Beispiel #2
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.
    """
    dial_db = PWState.entry.dial_db
    # 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,
                                                       dial_db)

        # -- "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, dial_db)
        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], dial_db)
            tmp += "            %s" % Lng.ELSE_FOLLOWS
            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_BUFFER_LEXATOM_PATH_TERMINATION"),
             goto_next_door,
             "        %s\n"        % Lng.ELSE_FOLLOWS,
             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
Beispiel #3
0
def __frame(FunctionName, CodeTxt, IteratorName, DoorIdReturn, dial_db):

    txt = [  \
          "static void\n" \
        + "%s(QUEX_TYPE_ANALYZER* me, QUEX_TYPE_LEXATOM* LexemeBegin, QUEX_TYPE_LEXATOM* LexemeEnd)\n" % FunctionName \
        + "{\n" \
    ]

    if IteratorName:
        state_router_adr   = DoorID.global_state_router(dial_db).related_address
        state_router_label = Lng.LABEL_STR_BY_ADR(state_router_adr)
        txt.extend([
            "#   define self (*me)\n",
            "/*  'QUEX_GOTO_STATE' requires 'QUEX_LABEL_STATE_ROUTER' */\n",
            "#   define QUEX_LABEL_STATE_ROUTER %s\n" % state_router_label
        ])

        # Following function refers to the global 'variable_db'
        txt.append(Lng.VARIABLE_DEFINITIONS(variable_db))

        txt.extend([
            "    (void)me;\n",
             Lng.COUNTER_SHIFT_VALUES(),
            "%s" % Lng.ML_COMMENT("Allow LexemeBegin == LexemeEnd (e.g. END_OF_STREAM)\n"
                                  "=> Caller does not need to check\n"
                                  "BUT, if so quit immediately after 'shift values'."),
            "    __quex_assert(LexemeBegin <= LexemeEnd);\n",
            "    %s" % Lng.IF("LexemeBegin", "==", "LexemeEnd"), 
            "        %s\n" % Lng.PURE_RETURN,
            "    %s\n" % Lng.END_IF,
            "    %s = LexemeBegin;\n" % IteratorName
        ])

    txt.extend(CodeTxt)

    if IteratorName:
        door_id_failure     = DoorID.incidence(E_IncidenceIDs.MATCH_FAILURE, dial_db)
        door_id_bad_lexatom = DoorID.incidence(E_IncidenceIDs.BAD_LEXATOM, dial_db)

        txt.append(
              "%s /* TERMINAL: BAD_LEXATOM */\n;\n"  % Lng.LABEL(door_id_bad_lexatom)
            # BETTER: A lexeme that is 'counted' has already matched!
            #         => FAILURE is impossible!
            # "%s /* TERMINAL: FAILURE     */\n%s\n" % Lng.UNREACHABLE
            + "%s /* TERMINAL: FAILURE     */\n%s\n" % (Lng.LABEL(door_id_failure), 
                                                        Lng.GOTO(DoorIdReturn, dial_db))
        )
        txt.append(
             "%s\n" % Lng.LABEL(DoorIdReturn)
           + "%s\n" % Lng.COMMENT("Assert: lexeme in codec's character boundaries.") \
           + "     __quex_assert(%s == LexemeEnd);\n" % IteratorName \
           + "    return;\n" \
           + "".join(generator.do_state_router(dial_db)) \
           + "%s\n" % Lng.UNDEFINE("self")
           + "%s\n" % Lng.UNDEFINE("QUEX_LABEL_STATE_ROUTER")
           # If there is no MATCH_FAILURE, then DoorIdBeyond is still referenced as 'gotoed',
           # but MATCH_FAILURE is never implemented, later on, because its DoorId is not 
           # referenced.
           + "$$<not-computed-gotos>----------------------------------------------\n"
           + "     %s /* in QUEX_GOTO_STATE       */\n" % Lng.GOTO(DoorID.global_state_router(dial_db), dial_db)
           + "     %s /* to BAD_LEXATOM           */\n" % Lng.GOTO(DoorID.incidence(E_IncidenceIDs.BAD_LEXATOM, dial_db), dial_db)
           + "$$------------------------------------------------------------------\n"
           + "    %s\n" % Lng.COMMENT("Avoid compiler warning: 'Unused labels'") \
           + "    %s\n" % Lng.GOTO(door_id_failure, dial_db) \
           + "    (void)target_state_index;\n"
           + "    (void)target_state_else_index;\n"
        )

    txt.append("}\n")

    return "".join(Lng.GET_PLAIN_STRINGS(txt, dial_db))