##language:zh ''' 含有章节索引的中文 文章模板 ''' -- 218.4.189.4 [<>] <> = Python 上的Prolog解释器 = ''简述'' == WAM虚拟机 == 第一步, WAM虚拟机. 解释执行gprolog产生的wam代码 === 分析wam代码 === prolog代码: {{{ appen([],L,L). appen([H|T],Y,[H|Z]):-appen(T,Y,Z). go:- appen([1],[1,2],[2,3]). :- initialization( go ). }}} wam代码形如: {{{ % compiler: GNU Prolog 1.2.16 (Sep 19 2002) % file : t3.pl % date : 1 14 2005 % time : 21:47:24 file_name('G:\\MYPRO~1\\projects\\PUREPR~1\\current\\test\\t3.pl'). predicate(appen/3,1,static,private,user,[ switch_on_term(1,2,fail,4,fail), label(1), try_me_else(3), label(2), get_nil(0), get_value(x(2),1), proceed, label(3), trust_me_else_fail, label(4), get_list(0), unify_variable(x(3)), unify_variable(x(0)), get_list(2), unify_value(x(3)), unify_variable(x(2)), execute(appen/3)]). predicate(go/0,4,static,private,user,[ put_list(0), unify_integer(1), unify_nil, put_list(1), unify_integer(1), unify_list, unify_integer(2), unify_nil, put_list(2), unify_integer(2), unify_list, unify_integer(3), unify_nil, execute(appen/3)]). directive(6,user,[ execute(go/0)]). }}} 分析代码, 结果是一个代码树: {{{ #!python import re rerem = r"\%.*$" statment = r"" refilename = r"\w*file_name\('(?P.*)'\).\w*$" st = { '"':r'^"([^"]|(\\"))*?"', "'":r"^'([^']|(\\'))*?'" } refn = re.compile(refilename) tb = { 'start':[(lambda s, c: c in lable, 'lable', ) ], '':() } class tock: def __init__(self): pass def setbuf(self, f): self.buf = f def parser(self): d = '' w = ' \n\t' nl = 0 for rl in self.buf: nl +=1 l = re.sub(rerem, '', rl) while l: if l[0] in "'\"": mc = re.match(st[l[0]], l) if not mc: print 'string error', rl, 'line', nl d = mc.group() yield ('l', d, rl, nl) l = l[mc.end():] d = '' if l[0] in '()[],.': if d: yield ('l', d.strip(w), rl, nl) d = '' yield ('s', l[0], rl, nl) l = l[1:] else: d += l[0] l = l[1:] class parser: def __init__(self): pass def setbuf(self, tocker): self.tocker = tocker def parse(self): import pprint pp = pprint.PrettyPrinter(indent=4) t = self.tocker.parser() ast = ('start',list()) p = [ast] for k, v, rl, nl in t: if k == 'l': p[-1][1].append(v) if v == '(': p[-1][1][-1] = (p[-1][1][-1],list()) p.append(p[-1][1][-1]) if v in ')]': p.pop() if v == '[': p[-1][1].append(('^list', list())) p.append(p[-1][1][-1]) if v == ',': if p[-1][0] == 'start': print 'stock error', rl, 'line', nl if v == '.': if p[-1][0] != 'start': print 'stock error', rl, 'line', nl pp.pprint(ast) def main(fn): t = tock() f = open(fn, 'r') t.setbuf(f) p = parser() p.setbuf(t) p.parse() if __name__ == '__main__': from sys import argv main(argv[1]) }}}