#!/usr/bin/python # # unresistricted grammar with dictionary interface # v.01 # Written by Shea Kauffman # # based upon the thue langauage by: # John Colagioia # and the interpreter by: # Frederic van der Plancke # # import string def find_all(s, pattern): """return ordered list of indexes where [pattern] appears in [s]; """ shift_on_match = 1 i = 0 indexes = [] while 1: i = string.find(s, pattern, i) if i >= 0: indexes.append(i) i = i + shift_on_match else: break return indexes class Rule: def __init__(self, lhs, rhs, output=None): self.lhs = lhs self.rhs = rhs self.output = output # UNUSED in current version def __str__(self): return "%s :- %s" % (self.lhs, self.rhs) def __repr__(self): return "Rule(%s,%s)" % (repr(self.lhs), repr(self.rhs)) class grammar: def __init__(self): self.rulebase = [] self.trace = False def __call__(self, item): while self[item] != item: item = self[item] return item def __getitem__(self, tape): matches = [] for rule in self.rulebase: indices = find_all(tape, rule.lhs) for i in indices: matches.append((i, rule)) if len(matches) == 0: if self.trace: print tape return tape # print matches (pos, rule) = min(matches) endpos = pos + len(rule.lhs) dataspace = tape[ : pos] + rule.rhs + tape[endpos : ] if self.trace: print tape, '->', dataspace return dataspace def __setitem__(self, lhs, rhs): self.rulebase.append(Rule(lhs, rhs)) def __repr__(self): ret = '' for rule in self.rulebase: ret = ret+'\n'+rule.__str__() return ret if __name__ == '__main__': #TESTS: #t1 t1 = grammar() t1['ZZZ'] = '...' #t2 t2 = grammar() t2['0_']='0--' t2['1_']='0' t2['10--']='01' t2['00--']='0--1' t2['_1--']='@' t2['_0--']='1' t2['_0']='' #t3 t3 = grammar() t3['__']='Hello, World!' #t4 t4 = grammar() t4['1_']='1++' t4['0_']='1' t4['01++']='10' t4['11++']='1++0' t4['_0']='_' t4['_1++']='10' #t5 t5 = grammar() t5['_+_'] = '<+|+>' t5['+>0'] = '0?+>' t5['+>1'] = '1?+>' t5['+>_'] = '<@0C_' t5['0<+'] = '<+0?' t5['1<+'] = '<+1?' t5['_<+'] = '_' t5['0@0?'] = '0?0@' t5['0@1?'] = '1?0@' t5['1@0?'] = '0?1@' t5['1@1?'] = '1?1@' t5['0@|'] = '|0@' t5['1@|'] = '|1@' t5['0@0@0C'] = '<@0C0' t5['0@0@1C'] = '<@0C1' t5['0@1@0C'] = '<@0C1' t5['0@1@1C'] = '<@1C0' t5['1@0@0C'] = '<@0C1' t5['1@0@1C'] = '<@1C0' t5['1@1@0C'] = '<@1C0' t5['1@1@1C'] = '<@1C1' t5['0?<@'] = '<?0@' t5['1?<@'] = '<?1@' t5['0?<?'] = '<?0?' t5['1?<?'] = '<?1?' t5['|<?'] = '<@|' t5['_<?'] = '_' t5['0?|<@'] = '|0@0@' t5['1?|<@'] = '|1@0@' t5['_<@|'] = '_|0@' t5['_|<@'] = '_' t5['_0C'] = '_' t5['_1C'] = '_1' t1.trace = True print t1 assert t1('ZZZZZZZZZZZZ') == '............' t2.trace = True print t2 assert t2('_1000000000000_') == '111111111111' t3.trace = True print t3 assert t3('__') == 'Hello, World!' t4.trace = True print t4 assert t4('_1111111111_') == '10000000000' t5.trace = True print t5 assert t5('_111100_+_10010_') == '_1001110_' d = grammar() d["server"]="mpilgrim" d["database"]="master" print d["server"] # mpilgrim print d["database"] # master print d["server is offline"] # mpilgrim is offline print d["database server is offline"] # master server is offline print d("database server is offline") # master mpilgrim is offline