含有章节索引的中文 文章模板

-- 218.4.189.4 [2005-01-15 02:55:42]

1. Python 上的Prolog解释器

简述

1.1. WAM虚拟机

第一步, WAM虚拟机. 解释执行gprolog产生的wam代码

1.1.1. 分析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])