def __frame(FunctionName, IteratorName, CodeTxt, DoorIdReturn, DoorIdBeyond): txt = [ \ "#ifdef __QUEX_OPTION_COUNTER\n" \ + "static void\n" \ + "%s(QUEX_TYPE_ANALYZER* me, QUEX_TYPE_LEXATOM* LexemeBegin, QUEX_TYPE_LEXATOM* LexemeEnd)\n" \ % FunctionName \ + "{\n" \ + "# define self (*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()) ] # Following function refers to the global 'variable_db' txt.append(Lng.VARIABLE_DEFINITIONS(variable_db)) txt.append( " (void)me;\n" " __QUEX_IF_COUNT_SHIFT_VALUES();\n" " /* Allow LexemeBegin == LexemeEnd (e.g. END_OF_STREAM)\n" " * => Caller does not need to check\n" " * BUT, if so quit immediately after 'shift values'. */\n" " __quex_assert(LexemeBegin <= LexemeEnd);\n" " if(LexemeBegin == LexemeEnd) return;\n" " %s = LexemeBegin;\n" % IteratorName ) txt.extend(CodeTxt) door_id_failure = DoorID.incidence(E_IncidenceIDs.MATCH_FAILURE) door_id_bad_lexatom = DoorID.incidence(E_IncidenceIDs.BAD_LEXATOM) txt.append( "%s /* TERMINAL: BAD_LEXATOM */\n;\n" % Lng.LABEL(door_id_bad_lexatom) + "%s /* TERMINAL: FAILURE */\n%s\n" % (Lng.LABEL(door_id_failure), Lng.GOTO(DoorIdBeyond)) ) txt.append( "%s:\n" % dial_db.get_label_by_door_id(DoorIdReturn) \ + " /* Assert: lexeme in codec's character boundaries. */\n" \ + " __quex_assert(%s == LexemeEnd);\n" % IteratorName \ + " return;\n" \ + "".join(generator.do_state_router()) \ + "# undef self\n" \ + "# undef QUEX_LABEL_STATE_ROUTER\n" # 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. + "# if ! defined(QUEX_OPTION_COMPUTED_GOTOS)\n" + " %s /* in QUEX_GOTO_STATE */\n" % Lng.GOTO(DoorID.global_state_router()) + " %s /* to BAD_LEXATOM */\n" % Lng.GOTO(DoorID.incidence(E_IncidenceIDs.BAD_LEXATOM)) + "# endif\n" + " /* Avoid compiler warning: Unused label for 'TERMINAL <BEYOND>' */\n" \ + " %s\n" % Lng.GOTO(DoorIdBeyond) \ + " %s\n" % Lng.GOTO(door_id_failure) \ + " (void)target_state_index;\n" + " (void)target_state_else_index;\n" + "}\n" \ + "#endif /* __QUEX_OPTION_COUNTER */\n" ) return "".join(Lng.GET_PLAIN_STRINGS(txt))
def __frame(FunctionName, IteratorName, CodeTxt, DoorIdReturn, DoorIdBeyond): txt = [ \ "#ifdef __QUEX_OPTION_COUNTER\n" \ + "static void\n" \ + "%s(QUEX_TYPE_ANALYZER* me, QUEX_TYPE_CHARACTER* LexemeBegin, QUEX_TYPE_CHARACTER* LexemeEnd)\n" \ % FunctionName \ + "{\n" \ + "# define self (*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()) ] # Following function refers to the global 'variable_db' txt.append(Lng.VARIABLE_DEFINITIONS(variable_db)) txt.append( " (void)me;\n" " __QUEX_IF_COUNT_SHIFT_VALUES();\n" " /* Allow LexemeBegin == LexemeEnd (e.g. END_OF_STREAM)\n" " * => Caller does not need to check\n" " * BUT, if so quit immediately after 'shift values'. */\n" " __quex_assert(LexemeBegin <= LexemeEnd);\n" " if(LexemeBegin == LexemeEnd) return;\n" " %s = LexemeBegin;\n" % IteratorName ) txt.extend(CodeTxt) door_id_failure = DoorID.incidence(E_IncidenceIDs.MATCH_FAILURE) txt.append( "%s /* TERMINAL: FAILURE */\n%s\n" % (Lng.LABEL(door_id_failure), Lng.GOTO(DoorIdBeyond)) ) txt.append( "%s:\n" % dial_db.get_label_by_door_id(DoorIdReturn) \ + " __quex_assert(%s == LexemeEnd); /* Otherwise, lexeme violates codec character boundaries. */\n" \ % IteratorName \ + " return;\n" \ + "".join(generator.do_state_router()) \ + "# undef self\n" \ + "# undef QUEX_LABEL_STATE_ROUTER\n" # 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. + "# if ! defined(QUEX_OPTION_COMPUTED_GOTOS)\n" + " %s /* in QUEX_GOTO_STATE */\n" % Lng.GOTO(DoorID.global_state_router()) + "# endif\n" + " /* Avoid compiler warning: Unused label for 'TERMINAL <BEYOND>' */\n" \ + " %s\n" % Lng.GOTO(DoorIdBeyond) \ + " %s\n" % Lng.GOTO(door_id_failure) \ + " (void)target_state_index;\n" + " (void)target_state_else_index;\n" + "}\n" \ + "#endif /* __QUEX_OPTION_COUNTER */\n" ) return "".join(Lng.GET_PLAIN_STRINGS(txt))
def do(StateRouterInfoList, dial_db): """Create code that allows to jump to a state based on an integer value. """ # NOTE: Do not use 'IfDoorIdReferencedCode' because the state router may # possibly not be tagged as 'gotoed', event if it is used. result = [ " __quex_assert_no_passage();\n", " %s /* prevent unused label */\n" % Lng.GOTO(DoorID.global_state_router(dial_db), dial_db), "%s\n" % Lng.LABEL(DoorID.global_state_router(dial_db), dial_db) ] if not Setup.computed_gotos_f and StateRouterInfoList: result.extend(__get_code(StateRouterInfoList)) return result
def RELOAD_SPECIAL(self, BeforeReloadAction, AfterReloadAction): assert self.__code_generation_reload_label is not None assert type(BeforeReloadAction) == list assert type(AfterReloadAction) == list result = [ cpp_reload_forward_str[0], "%s:\n" % self.__code_generation_reload_label, cpp_reload_forward_str[1], ] result.extend(BeforeReloadAction) result.append(cpp_reload_forward_str[2]) result.extend(AfterReloadAction) result.append(cpp_reload_forward_str[3]) dial_db.mark_door_id_as_gotoed(DoorID.global_state_router()) return result
def RELOAD_SPECIAL(self, BeforeReloadAction, AfterReloadAction): assert self.__code_generation_reload_label is not None assert type(BeforeReloadAction) == list assert type(AfterReloadAction) == list result = [ cpp_reload_forward_str[0], "%s:\n" % self.__code_generation_reload_label, cpp_reload_forward_str[1], ] result.extend(BeforeReloadAction) result.append(cpp_reload_forward_str[2]) result.extend(AfterReloadAction) result.append(cpp_reload_forward_str[3]) dial_db.mark_door_id_as_gotoed(DoorID.global_state_router()) return result
def do(StateRouterInfoList): """Create code that allows to jump to a state based on an integer value. """ # NOTE: Do not use 'IfDoorIdReferencedCode' because the state router may # possibly not be tagged as 'gotoed', event if it is used. prolog = "# ifndef QUEX_OPTION_COMPUTED_GOTOS\n" \ " __quex_assert_no_passage();\n" \ "%s\n" % Lng.LABEL(DoorID.global_state_router()) epilog = "# endif /* QUEX_OPTION_COMPUTED_GOTOS */\n" if len(StateRouterInfoList) == 0: code = [] else: code = __get_code(StateRouterInfoList) result = [ prolog ] result.extend(code) result.append(epilog) return result
def do(StateRouterInfoList): """Create code that allows to jump to a state based on an integer value. """ # NOTE: Do not use 'IfDoorIdReferencedCode' because the state router may # possibly not be tagged as 'gotoed', event if it is used. prolog = "# ifndef QUEX_OPTION_COMPUTED_GOTOS\n" \ " __quex_assert_no_passage();\n" \ "%s\n" % Lng.LABEL(DoorID.global_state_router()) epilog = "# endif /* QUEX_OPTION_COMPUTED_GOTOS */\n" if len(StateRouterInfoList) == 0: code = [] else: code = __get_code(StateRouterInfoList) result = [prolog] result.extend(code) result.append(epilog) return result
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
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 __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))