#!/usr/bin/env python3 from string import whitespace class TuringParser: def parse_string(self, string): return build_transition_table(string.split('\n')) def parse_file(self, path): with open(path) as insts: return self.build_transition_table(insts) def build_transition_table(self, insts): transitions = {} for inst in insts: condition, result = self.parse_inst(inst) transitions[condition] = result return transitions def parse_inst(self, inst): direcs = { 'l' : -1, 'r' : 1, 's' : 0 } inst = inst.strip(whitespace) from_state, tape_character, to_state, new_char, direc = \ inst.split(',') if not direc in direcs.keys(): raise Exception('Expected: l, r, or s instead of {0}'.format(direc)) return (from_state, tape_character), (to_state, new_char, direcs[direc]) class TuringMachine: def __init__(self, string, transitions, state='1'): self.initial = state self.string = string self.transitions = transitions self.reset() def reset(self): self.tape = list(self.string) self.state = self.initial self.pointer = 0 def step(self, steps=1): for i in range(steps): next(self) def __iter__(self): return self def __next__(self): if self.pointer >= len(self.tape): self.tape.append('_') try: to_state, new_char, direc = \ self.transitions[(self.state, self.tape[self.pointer])] except KeyError: raise StopIteration() if to_state == 'H': raise StopIteration() self.tape[self.pointer] = new_char self.state = to_state self.pointer += direc return (self.pointer, self.state, ''.join(self.tape))