Exemple #1
0
def reentry_preparation(Lng, PreConditionIDList, OnAfterMatchCode, dial_db):
    """Reentry preperation (without returning from the function."""
    # (*) Unset all pre-context flags which may have possibly been set
    unset_pre_context_flags_str = Lng.PRE_CONTEXT_RESET(PreConditionIDList)
    on_after_match_str = Lng.SOURCE_REFERENCED(OnAfterMatchCode)
    return [
        "\n%s\n" % Lng.LABEL(DoorID.return_with_on_after_match(dial_db)),
        Lng.COMMENT("RETURN -- after executing 'on_after_match' code."),
        on_after_match_str,
        "    %s\n\n" % Lng.PURE_RETURN,
        #
        "\n%s\n" % Lng.LABEL(DoorID.continue_with_on_after_match(dial_db)),
        Lng.COMMENT("CONTINUE -- after executing 'on_after_match' code."),
        on_after_match_str,
        #
        "\n%s\n" % Lng.LABEL(DoorID.continue_without_on_after_match(dial_db)),
        Lng.COMMENT(
            "CONTINUE -- without executing 'on_after_match' (e.g. on FAILURE)."
        ),
        "\n",
        #
        __assert_no_mode_change,
        "\n",
        __return_if_queue_full_or_simple_analyzer,
        "\n",
        unset_pre_context_flags_str,
        "\n%s\n" % Lng.GOTO(DoorID.global_reentry(dial_db), dial_db),
    ]
Exemple #2
0
def reentry_preparation(Lng, PreConditionIDList, OnAfterMatchCode):
    """Reentry preperation (without returning from the function."""
    # (*) Unset all pre-context flags which may have possibly been set
    unset_pre_context_flags_str = Lng.PRE_CONTEXT_RESET(PreConditionIDList)

    if OnAfterMatchCode is not None:
        on_after_match_str = Lng.SOURCE_REFERENCED(OnAfterMatchCode)
    else:
        on_after_match_str = ""

    txt = [ 
        "\n%s\n"  % Lng.LABEL(DoorID.return_with_on_after_match()), 
        Lng.COMMENT("RETURN -- after executing 'on_after_match' code."),
        on_after_match_str,
        "    %s\n\n" % Lng.PURE_RETURN,
        #
        "\n%s\n" % Lng.LABEL(DoorID.continue_with_on_after_match()), 
        Lng.COMMENT("CONTINUE -- after executing 'on_after_match' code."),
        on_after_match_str,
        #
        "\n%s\n" % Lng.LABEL(DoorID.continue_without_on_after_match()),
        Lng.COMMENT("CONTINUE -- without executing 'on_after_match' (e.g. on FAILURE)."), "\n",
        #
        __return_if_queue_full_or_simple_analyzer, "\n",
        __return_if_mode_changed, "\n",
        #
        unset_pre_context_flags_str,
        "\n%s\n" % Lng.GOTO(DoorID.global_reentry()), 
    ]

    return txt
def _code_terminal_on_bad_indentation_character(code, ISetup, ModeName, 
                                                incidence_db, BadIndentationIid):
    if ISetup.bad_character_set.get() is None:
        return
    on_bad_indentation_txt = Lng.SOURCE_REFERENCED(incidence_db[E_IncidenceIDs.INDENTATION_BAD])
    code.extend([
        "%s\n" % Lng.LABEL(DoorID.incidence(BadIndentationIid)),
        "#define BadCharacter (me->buffer._input_p[-1])\n",
        "%s\n" % on_bad_indentation_txt,
        "#undef  BadCharacter\n",
        "%s\n" % Lng.GOTO(DoorID.global_reentry())
    ])
def _code_terminal_on_bad_indentation_character(code, ISetup, ModeName,
                                                incidence_db,
                                                BadIndentationIid):
    if ISetup.bad_character_set.get() is None:
        return
    on_bad_indentation_txt = Lng.SOURCE_REFERENCED(
        incidence_db[E_IncidenceIDs.INDENTATION_BAD])
    code.extend([
        "%s\n" % Lng.LABEL(DoorID.incidence(BadIndentationIid)),
        "#define BadCharacter (me->buffer._input_p[-1])\n",
        "%s\n" % on_bad_indentation_txt, "#undef  BadCharacter\n",
        "%s\n" % Lng.GOTO(DoorID.global_reentry())
    ])
def PPT_indentation_handler_suppressed_newline(MHI, SmSuppressedNewline):
    """Generate a PPT for suppressed newline, that is:

        -- its PatternPriority.
        -- the Pattern object.
        -- the Terminal object.

    The terminal simply jumpts to the re-entry of the lexical analyzer.
    """
    assert SmSuppressedNewline is not None

    pattern = Pattern(SmSuppressedNewline, 
                      PatternString="<indentation suppressed newline>")
    code     = CodeTerminal([Lng.GOTO(DoorID.global_reentry())])
    # terminal = terminal_factory.do(E_TerminalType.PLAIN, code)
    # terminal.set_name("INDENTATION COUNTER: SUPPRESSED_NEWLINE")

    return PPT(PatternPriority(MHI, 1), pattern, code)
Exemple #6
0
def PPT_indentation_handler_suppressed_newline(MHI, SmSuppressedNewline):
    """Generate a PPT for suppressed newline, that is:

        -- its PatternPriority.
        -- the Pattern object.
        -- the Terminal object.

    The terminal simply jumpts to the re-entry of the lexical analyzer.
    """
    assert SmSuppressedNewline is not None

    pattern = Pattern(SmSuppressedNewline,
                      PatternString="<indentation suppressed newline>")
    code = CodeTerminal([Lng.GOTO(DoorID.global_reentry())])
    # terminal = terminal_factory.do(E_TerminalType.PLAIN, code)
    # terminal.set_name("INDENTATION COUNTER: SUPPRESSED_NEWLINE")

    return PPT(PatternPriority(MHI, 1), pattern, code)
Exemple #7
0
def _analyzer_function(StateMachineName, Setup, variable_definitions, 
                       function_body, ModeNameList=[]):
    """EngineClassName = name of the structure that contains the engine state.
                         if a mode of a complete quex environment is created, this
                         is the mode name. otherwise, any name can be chosen. 
       SingleModeAnalyzerF = False if a mode for a quex engine is to be created. True
                           if a stand-alone lexical engine is required (without the
                           complete mode-handling framework of quex).
    """              
    Lng = Setup.language_db
    SingleModeAnalyzerF = Setup.single_mode_analyzer_f

    mode_definition_str   = ""
    mode_undefinition_str = ""
    if len(ModeNameList) != 0 and not SingleModeAnalyzerF: 
        L = max(map(lambda name: len(name), ModeNameList))
        mode_definition_str = "".join(
            "#   define %s%s    (QUEX_NAME(%s))\n" % (name, " " * (L- len(name)), name)
            for name in ModeNameList
        )
        mode_undefinition_str = "".join(
            "#   undef %s\n" % name 
            for name in ModeNameList
        )

    function_signature_str = __function_signature.replace("$$STATE_MACHINE_NAME$$", 
                                                          StateMachineName)
    txt = [
        "#include <quex/code_base/temporary_macros_on>\n",
        function_signature_str,
        # 
        # Macro definitions
        #
        "#   ifdef     self\n",
        "#       undef self\n",
        "#   endif\n",
        "#   define self (*((QUEX_TYPE_ANALYZER*)me))\n",
        "/*  'QUEX_GOTO_STATE' requires 'QUEX_LABEL_STATE_ROUTER' */\n",
        "#   define QUEX_LABEL_STATE_ROUTER %s\n" % dial_db.get_label_by_door_id(DoorID.global_state_router()),
        mode_definition_str,
        Lng.LEXEME_MACRO_SETUP(),
        #
        variable_definitions,
        #
        comment_on_post_context_position_init_str,
        "#   if    defined(QUEX_OPTION_AUTOMATIC_ANALYSIS_CONTINUATION_ON_MODE_CHANGE) \\\n",
        "       || defined(QUEX_OPTION_ASSERTS)\n",
        "    me->DEBUG_analyzer_function_at_entry = me->current_analyzer_function;\n",
        "#   endif\n",
        #
        # Entry to the actual function body
        #
        "%s\n" % Lng.LABEL(DoorID.global_reentry()),
        "    %s\n" % Lng.LEXEME_START_SET(),
        "    QUEX_LEXEME_TERMINATING_ZERO_UNDO(&me->buffer);\n",
    ]

    txt.extend(function_body)

    # -- prevent the warning 'unused variable'
    txt.extend([ 
        "\n",                                                                                             
        "    __quex_assert_no_passage();\n", 
        "\n",                                                                                             
        "    /* Following labels are referenced in macros. It cannot be detected\n"
        "     * whether the macros are applied in user code or not. To avoid compiler.\n"
        "     * warnings of unused labels, they are referenced in unreachable code.   */\n"
        "    %s /* in RETURN                */\n" % Lng.GOTO(DoorID.return_with_on_after_match()),
        "    %s /* in CONTINUE              */\n" % Lng.GOTO(DoorID.continue_with_on_after_match()),
        "    %s /* in CONTINUE and skippers */\n" % Lng.GOTO(DoorID.continue_without_on_after_match()),
        "#   if ! defined(QUEX_OPTION_COMPUTED_GOTOS)\n",
        "    %s /* in QUEX_GOTO_STATE       */\n" % Lng.GOTO(DoorID.global_state_router()),
        "#   endif\n",
        "\n",
        "    /* Prevent compiler warning 'unused variable'.                           */\n",
        "    (void)QUEX_LEXEME_NULL;\n",                                    
        "    (void)QUEX_NAME_TOKEN(DumpedTokenIdObject);\n",                
        "    /* target_state_index and target_state_else_index appear when \n",
        "     * QUEX_GOTO_STATE is used without computed goto-s.                      */\n",
        "    (void)target_state_index;\n",
        "    (void)target_state_else_index;\n",
        #
        # Macro undefinitions
        # 
        lexeme_macro_clean_up,
        mode_undefinition_str,
        "#   undef self\n",
        "#   undef QUEX_LABEL_STATE_ROUTER\n",
        "}\n",
        "#include <quex/code_base/temporary_macros_off>\n",
    ])
    return txt
Exemple #8
0
def _analyzer_function(StateMachineName, Setup, variable_definitions,
                       function_body, dial_db, ModeNameList):
    """EngineClassName = name of the structure that contains the engine state.
                         if a mode of a complete quex environment is created, this
                         is the mode name. otherwise, any name can be chosen. 
    """
    Lng = Setup.language_db

    function_signature_str = __function_signature.replace(
        "$$STATE_MACHINE_NAME$$", StateMachineName)

    state_router_adr = DoorID.global_state_router(dial_db).related_address
    txt = [
        function_signature_str,
        # Macro definitions
        #
        Lng.DEFINE_SELF("me"),
        Lng.MODE_DEFINITION(ModeNameList),
        "/*  'QUEX_GOTO_STATE' requires 'QUEX_LABEL_STATE_ROUTER' */\n",
        "#   define QUEX_LABEL_STATE_ROUTER %s\n" %
        Lng.LABEL_STR_BY_ADR(state_router_adr),
        Lng.DEFINE_LEXEME_VARIABLES(),
        #
        variable_definitions,
        #
        comment_on_post_context_position_init_str,
        "#   if defined(QUEX_OPTION_ASSERTS)\n",
        "    me->DEBUG_analyzer_function_at_entry = me->current_analyzer_function;\n",
        "#   endif\n",
        #
        # Entry to the actual function body
        #
        "%s\n" % Lng.LABEL(DoorID.global_reentry(dial_db)),
        "    %s\n" % Lng.LEXEME_START_SET(),
        "    QUEX_LEXEME_TERMINATING_ZERO_UNDO(&me->buffer);\n",
    ]

    txt.extend(function_body)

    # -- prevent the warning 'unused variable'
    txt.extend([
        "\n",
        "    __quex_assert_no_passage();\n",
        "\n",
        "    /* Following labels are referenced in macros. It cannot be detected\n"
        "     * whether the macros are applied in user code or not. To avoid compiler.\n"
        "     * warnings of unused labels, they are referenced in unreachable code.   */\n"
        "    %s /* in RETURN                */\n" %
        Lng.GOTO(DoorID.return_with_on_after_match(dial_db), dial_db),
        "    %s /* in CONTINUE              */\n" %
        Lng.GOTO(DoorID.continue_with_on_after_match(dial_db), dial_db),
        "    %s /* in CONTINUE and skippers */\n" %
        Lng.GOTO(DoorID.continue_without_on_after_match(dial_db), dial_db),
        "$$<not-computed-gotos>----------------------------------------------\n",
        "    %s /* in QUEX_GOTO_STATE       */\n" %
        Lng.GOTO(DoorID.global_state_router(dial_db), dial_db),
        "$$------------------------------------------------------------------\n",
        "\n",
        "    /* Prevent compiler warning 'unused variable'.                           */\n",
        "    (void)QUEX_NAME(LexemeNull);\n",
        "    /* target_state_index and target_state_else_index appear when \n",
        "     * QUEX_GOTO_STATE is used without computed goto-s.                      */\n",
        "    (void)target_state_index;\n",
        "    (void)target_state_else_index;\n",
        #
        # Macro undefinitions
        #
        Lng.UNDEFINE_LEXEME_VARIABLES(),
        Lng.MODE_UNDEFINITION(ModeNameList),
        "#   undef self\n",
        "#   undef QUEX_LABEL_STATE_ROUTER\n",
        "}\n",
    ])
    return txt
Exemple #9
0
def _analyzer_function(StateMachineName, Setup, variable_definitions, 
                       function_body, ModeNameList=[]):
    """EngineClassName = name of the structure that contains the engine state.
                         if a mode of a complete quex environment is created, this
                         is the mode name. otherwise, any name can be chosen. 
       SingleModeAnalyzerF = False if a mode for a quex engine is to be created. True
                           if a stand-alone lexical engine is required (without the
                           complete mode-handling framework of quex).
    """              
    Lng = Setup.language_db
    SingleModeAnalyzerF = Setup.single_mode_analyzer_f

    mode_definition_str   = ""
    mode_undefinition_str = ""
    if len(ModeNameList) != 0 and not SingleModeAnalyzerF: 
        L = max(map(lambda name: len(name), ModeNameList))
        mode_definition_str = "".join(
            "#   define %s%s    (QUEX_NAME(%s))\n" % (name, " " * (L- len(name)), name)
            for name in ModeNameList
        )
        mode_undefinition_str = "".join(
            "#   undef %s\n" % name 
            for name in ModeNameList
        )

    function_signature_str = __function_signature.replace("$$STATE_MACHINE_NAME$$", 
                                                          StateMachineName)
    txt = [
        "#include <quex/code_base/temporary_macros_on>\n",
        function_signature_str,
        # 
        # Macro definitions
        #
        "#   ifdef     self\n",
        "#       undef self\n",
        "#   endif\n",
        "#   define self (*((QUEX_TYPE_ANALYZER*)me))\n",
        "/*  'QUEX_GOTO_STATE' requires 'QUEX_LABEL_STATE_ROUTER' */\n",
        "#   define QUEX_LABEL_STATE_ROUTER %s\n" % dial_db.get_label_by_door_id(DoorID.global_state_router()),
        mode_definition_str,
        Lng.LEXEME_MACRO_SETUP(),
        #
        variable_definitions,
        #
        comment_on_post_context_position_init_str,
        "#   if    defined(QUEX_OPTION_AUTOMATIC_ANALYSIS_CONTINUATION_ON_MODE_CHANGE) \\\n",
        "       || defined(QUEX_OPTION_ASSERTS)\n",
        "    me->DEBUG_analyzer_function_at_entry = me->current_analyzer_function;\n",
        "#   endif\n",
        #
        # Entry to the actual function body
        #
        "%s\n" % Lng.LABEL(DoorID.global_reentry()),
        "    %s\n" % Lng.LEXEME_START_SET(),
        "    QUEX_LEXEME_TERMINATING_ZERO_UNDO(&me->buffer);\n",
    ]

    txt.extend(function_body)

    # -- prevent the warning 'unused variable'
    txt.extend([ 
        "\n",                                                                                             
        "    __quex_assert_no_passage();\n", 
        "\n",                                                                                             
        "    /* Following labels are referenced in macros. It cannot be detected\n"
        "     * whether the macros are applied in user code or not. To avoid compiler.\n"
        "     * warnings of unused labels, they are referenced in unreachable code.   */\n"
        "    %s /* in RETURN                */\n" % Lng.GOTO(DoorID.return_with_on_after_match()),
        "    %s /* in CONTINUE              */\n" % Lng.GOTO(DoorID.continue_with_on_after_match()),
        "    %s /* in CONTINUE and skippers */\n" % Lng.GOTO(DoorID.continue_without_on_after_match()),
        "#   if ! defined(QUEX_OPTION_COMPUTED_GOTOS)\n",
        "    %s /* in QUEX_GOTO_STATE       */\n" % Lng.GOTO(DoorID.global_state_router()),
        "#   endif\n",
        "\n",
        "    /* Prevent compiler warning 'unused variable'.                           */\n",
        "    (void)QUEX_LEXEME_NULL;\n",                                    
        "    (void)QUEX_NAME_TOKEN(DumpedTokenIdObject);\n",                
        "    /* target_state_index and target_state_else_index appear when \n",
        "     * QUEX_GOTO_STATE is used without computed goto-s.                      */\n",
        "    (void)target_state_index;\n",
        "    (void)target_state_else_index;\n",
        #
        # Macro undefinitions
        # 
        lexeme_macro_clean_up,
        mode_undefinition_str,
        "#   undef self\n",
        "#   undef QUEX_LABEL_STATE_ROUTER\n",
        "}\n",
        "#include <quex/code_base/temporary_macros_off>\n",
    ])
    return txt
Exemple #10
0
    def _prepare_indentation_counter(self, MHI, Loopers, CaMap, ReloadState):
        """Prepare indentation counter. An indentation counter is implemented by 
        the following:

        'newline' pattern --> triggers as soon as an UNSUPPRESSED newline occurs. 
                          --> entry to the INDENTATION COUNTER.

        'suppressed newline' --> INDENTATION COUNTER is NOT triggered.
         
        The supressed newline pattern is longer (and has precedence) over the
        newline pattern. With the suppressed newline it is possible to write
        lines which overstep the newline (see backslahs in Python, for example).

        RETURNS: List of:
                 [0] newline PPT and
                 [1] optionally the PPT of the newline suppressor.

        The primary pattern action pair list is to be the head of all pattern
        action pairs.

        MHI = Mode hierarchie index defining the priority of the current mode.
        """
        ISetup = Loopers.indentation_handler
        if ISetup is None: return [], [], []

        check_indentation_setup(ISetup)

        # Isolate the pattern objects, so alternatively,
        # they may be treated in 'indentation_counter'.
        pattern_newline = ISetup.pattern_newline.clone()
        if ISetup.pattern_suppressed_newline:
            pattern_suppressed_newline = ISetup.pattern_suppressed_newline.clone(
            )
        else:
            pattern_suppressed_newline = None

        new_analyzer_list,     \
        new_terminal_list,     \
        required_register_set, \
        run_time_counter_f     = indentation_counter.do(self.terminal_factory.mode_name,
                                                        CaMap,
                                                        ISetup,
                                                        self.terminal_factory.incidence_db,
                                                        ReloadState,
                                                        self.terminal_factory.dial_db)

        self.terminal_factory.run_time_counter_required_f |= run_time_counter_f

        self.required_register_set.update(required_register_set)

        # 'newline' triggers --> indentation counter
        pattern = pattern_newline.finalize(CaMap)
        pattern = pattern.clone_with_new_incidence_id(
            E_IncidenceIDs.INDENTATION_HANDLER)
        terminal = self._terminal_goto_to_looper(new_analyzer_list,
                                                 None,
                                                 "<indentation handler>",
                                                 required_register_set,
                                                 Pattern=pattern)
        new_ppt_list = [PPT(PatternPriority(MHI, 0), pattern, terminal)]

        if pattern_suppressed_newline is not None:
            # 'newline-suppressor' causes following 'newline' to be ignored.
            # => next line not subject to new indentation counting.
            new_incidence_id = dial.new_incidence_id()
            pattern = pattern_suppressed_newline.finalize(CaMap)
            pattern = pattern.clone_with_new_incidence_id(new_incidence_id)
            door_id = DoorID.global_reentry(self.terminal_factory.dial_db)
            code = CodeTerminal(
                [Lng.GOTO(door_id, self.terminal_factory.dial_db)])
            new_ppt_list.append(
                PPT(
                    PatternPriority(MHI, 1), pattern,
                    self.terminal_factory.do_plain(
                        code, pattern,
                        "INDENTATION COUNTER SUPPRESSED_NEWLINE: ")))

        return new_ppt_list, new_analyzer_list, new_terminal_list