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 ]
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
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))