def do(cls, Target): if isinstance(Target, TransitionCode): return Target elif isinstance(Target, (str, unicode)) or isinstance(Target, list): return TransitionCode(Target) elif isinstance(Target, DoorID): return TransitionCodeByDoorId(Target) elif isinstance(Target, TargetByStateKey): if Target.uniform_door_id is not None: return TransitionCodeByDoorId(Target.uniform_door_id) assert Target.scheme_id is not None variable_name = require_scheme_variable(Target.scheme_id, Target.iterable_door_id_scheme(), cls.state, cls.state_db) return TransitionCode(Lng.GOTO_BY_VARIABLE("%s[%s]" % (variable_name, cls.state_key_str))) else: assert False
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