def do_match_pattern(self, Code, ThePattern): """A pattern has matched.""" lexeme_begin_f, \ terminating_zero_f, \ adorned_code = self.__adorn_user_code(Code, MatchF=True) # IMPORTANT: Terminals can be entered by any kind of 'GOTO'. In order to # be on the safe side, BIPD should be started from within the # terminal itself. Otherwise, it may be missed due to some # coding negligence. text = [] if ThePattern.bipd_sm is not None: TerminalFactory.do_bipd_entry_and_return(text, ThePattern) text.extend([ self.get_counter_text(ThePattern), # adorned_code, # Lng.GOTO(DoorID.continue_with_on_after_match()) ]) code = CodeTerminal(text, SourceReference=Code.sr, PureCode=Code.get_pure_code(), LexemeRelevanceF=True, LexemeBeginF=lexeme_begin_f, LexemeTerminatingZeroF=terminating_zero_f) name = TerminalFactory.name_pattern_match_terminal( ThePattern.pattern_string()) return Terminal(code, name)
def do_match_pattern(self, Code, ThePattern): """A pattern has matched.""" lexeme_begin_f, \ terminating_zero_f, \ adorned_code = self.__adorn_user_code(Code, MatchF=True) # IMPORTANT: Terminals can be entered by any kind of 'GOTO'. In order to # be on the safe side, BIPD should be started from within the # terminal itself. Otherwise, it may be missed due to some # coding negligence. text = [] if ThePattern.bipd_sm is not None: TerminalFactory.do_bipd_entry_and_return(text, ThePattern) text.extend([ self.get_counter_text(ThePattern), # adorned_code, # Lng.GOTO(DoorID.continue_with_on_after_match()) ]) code = CodeTerminal(text, SourceReference = Code.sr, PureCode = Code.get_pure_code(), LexemeRelevanceF = True, LexemeBeginF = lexeme_begin_f, LexemeTerminatingZeroF = terminating_zero_f) name = TerminalFactory.name_pattern_match_terminal(ThePattern.pattern_string()) return Terminal(code, name)
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 action(ThePattern, PatternName): txt = [] if ThePattern.sm_bipd_to_be_reversed is not None: terminal_factory.do_bipd_entry_and_return(txt, pattern) txt.append("%s\n" % Lng.STORE_LAST_CHARACTER( blackboard.required_support_begin_of_line())) txt.append("%s\n" % Lng.LEXEME_TERMINATING_ZERO_SET(True)) txt.append('printf("%19s \'%%s\'\\n", Lexeme); fflush(stdout);\n' % PatternName) if "->1" in PatternName: txt.append( "me->current_analyzer_function = QUEX_NAME(M_analyzer_function);\n" ) elif "->2" in PatternName: txt.append( "me->current_analyzer_function = QUEX_NAME(M2_analyzer_function);\n" ) if "CONTINUE" in PatternName: txt.append("") elif "STOP" in PatternName: txt.append( "QUEX_NAME(MF_error_code_set_if_first)(me, E_Error_UnitTest_Termination); return;\n" ) else: txt.append("return;\n") txt.append( "%s\n" % Lng.GOTO(DoorID.continue_with_on_after_match(dial_db), dial_db)) ## print "#", txt return CodeTerminal(txt)
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), ]
def action(ThePattern, PatternName): txt = [] if ThePattern.bipd_sm is not None: TerminalFactory.do_bipd_entry_and_return(txt, pattern) txt.append("%s\n" % Lng.STORE_LAST_CHARACTER( blackboard.required_support_begin_of_line())) txt.append("%s\n" % Lng.LEXEME_TERMINATING_ZERO_SET(True)) txt.append('printf("%19s \'%%s\'\\n", Lexeme); fflush(stdout);\n' % PatternName) if "->1" in PatternName: txt.append( "me->current_analyzer_function = QUEX_NAME(Mr_analyzer_function);\n" ) elif "->2" in PatternName: txt.append( "me->current_analyzer_function = QUEX_NAME(Mrs_analyzer_function);\n" ) if "CONTINUE" in PatternName: txt.append("") elif "STOP" in PatternName: txt.append("return false;\n") else: txt.append("return true;\n") txt.append("%s\n" % Lng.GOTO(DoorID.continue_with_on_after_match())) ## print "#", txt return CodeTerminal(txt)
def HEADER_DEFINITIONS(self): return blue_print(cpp_header_definition_str, [ ("$$CONTINUE_WITH_ON_AFTER_MATCH$$", dial_db.get_label_by_door_id( DoorID.continue_with_on_after_match())), ("$$RETURN_WITH_ON_AFTER_MATCH$$", dial_db.get_label_by_door_id( DoorID.return_with_on_after_match())), ])
def action(ThePattern, PatternName): txt = [] if ThePattern.bipd_sm is not None: TerminalFactory.do_bipd_entry_and_return(txt, pattern) txt.append("%s\n" % Lng.STORE_LAST_CHARACTER(blackboard.required_support_begin_of_line())) txt.append("%s\n" % Lng.LEXEME_TERMINATING_ZERO_SET(True)) txt.append('printf("%19s \'%%s\'\\n", Lexeme); fflush(stdout);\n' % PatternName) if "->1" in PatternName: txt.append("me->current_analyzer_function = QUEX_NAME(Mr_analyzer_function);\n") elif "->2" in PatternName: txt.append("me->current_analyzer_function = QUEX_NAME(Mrs_analyzer_function);\n") if "CONTINUE" in PatternName: txt.append("") elif "STOP" in PatternName: txt.append("return false;\n") else: txt.append("return true;\n") txt.append("%s\n" % Lng.GOTO(DoorID.continue_with_on_after_match())) ## print "#", txt return CodeTerminal(txt)
def HEADER_DEFINITIONS(self): return blue_print(cpp_header_definition_str, [ ("$$CONTINUE_WITH_ON_AFTER_MATCH$$", dial_db.get_label_by_door_id(DoorID.continue_with_on_after_match())), ("$$RETURN_WITH_ON_AFTER_MATCH$$", dial_db.get_label_by_door_id(DoorID.return_with_on_after_match())), ])
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
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