含有章节索引的中文 文章模板
-- 218.4.189.4 [DateTime(2005-01-15T02:55:42Z)] TableOfContents
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)]).
分析代码, 结果是一个代码树:
1 import re
2
3 rerem = r"\%.*$"
4 statment = r""
5 refilename = r"\w*file_name\('(?P<filename>.*)'\).\w*$"
6 st = { '"':r'^"([^"]|(\\"))*?"',
7 "'":r"^'([^']|(\\'))*?'"
8 }
9 refn = re.compile(refilename)
10
11 tb = {
12 'start':[(lambda s, c: c in lable,
13 'lable', )
14 ],
15 '':()
16 }
17
18
19 class tock:
20 def __init__(self):
21 pass
22 def setbuf(self, f):
23 self.buf = f
24 def parser(self):
25 d = ''
26 w = ' \n\t'
27 nl = 0
28 for rl in self.buf:
29 nl +=1
30 l = re.sub(rerem, '', rl)
31 while l:
32 if l[0] in "'\"":
33 mc = re.match(st[l[0]], l)
34 if not mc:
35 print 'string error', rl, 'line', nl
36 d = mc.group()
37 yield ('l', d, rl, nl)
38 l = l[mc.end():]
39 d = ''
40 if l[0] in '()[],.':
41 if d:
42 yield ('l', d.strip(w), rl, nl)
43 d = ''
44 yield ('s', l[0], rl, nl)
45 l = l[1:]
46 else:
47 d += l[0]
48 l = l[1:]
49
50 class parser:
51 def __init__(self):
52 pass
53 def setbuf(self, tocker):
54 self.tocker = tocker
55 def parse(self):
56 import pprint
57 pp = pprint.PrettyPrinter(indent=4)
58
59 t = self.tocker.parser()
60 ast = ('start',list())
61 p = [ast]
62 for k, v, rl, nl in t:
63 if k == 'l':
64 p[-1][1].append(v)
65 if v == '(':
66 p[-1][1][-1] = (p[-1][1][-1],list())
67 p.append(p[-1][1][-1])
68 if v in ')]':
69 p.pop()
70 if v == '[':
71 p[-1][1].append(('^list', list()))
72 p.append(p[-1][1][-1])
73 if v == ',':
74 if p[-1][0] == 'start':
75 print 'stock error', rl, 'line', nl
76 if v == '.':
77 if p[-1][0] != 'start':
78 print 'stock error', rl, 'line', nl
79
80 pp.pprint(ast)
81
82 def main(fn):
83 t = tock()
84 f = open(fn, 'r')
85 t.setbuf(f)
86 p = parser()
87 p.setbuf(t)
88 p.parse()
89
90
91 if __name__ == '__main__':
92 from sys import argv
93 main(argv[1])