为python编辑norvig的scheme解释器

2024-06-17 10:06:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为racket程序编辑Norvig的lispy.py模式到python解释器,在该程序中,除了他包含的过程之外,我还使用open-input-stringstring-replace

看起来我可以将相应的python定义添加到他的add_globals()函数中,如下所示


    def add_globals(self):
        "Add some Scheme standard procedures."
        import math, cmath, operator as op
        self.update(vars(math))
        self.update(vars(cmath))
        self.update({
         '+':op.add, '-':op.sub, '*':op.mul, '/':op.div, 'not':op.not_, 
         '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, 
         'equal?':op.eq, 'eq?':op.is_, 'length':len, 'cons':cons,
         'car':lambda x:x[0], 'cdr':lambda x:x[1:], 'append':op.add,  
         'list':lambda *x:list(x), 'list?': lambda x:isa(x,list),
         'null?':lambda x:x==[], 'symbol?':lambda x: isa(x, Symbol),
         'boolean?':lambda x: isa(x, bool), 'pair?':is_pair, 
         'port?': lambda x:isa(x,file), 'apply':lambda proc,l: proc(*l), 
         'eval':lambda x: eval(expand(x)), 'load':lambda fn: load(fn), 'call/cc':callcc,
         'open-input-file':open,'close-input-port':lambda p: p.file.close(), 
         'open-output-file':lambda f:open(f,'w'), 'close-output-port':lambda p: p.close(),
         'eof-object?':lambda x:x is eof_object, 'read-char':readchar, 
        #  Additions below
         'open-input-string':lambda x:x.decode('string_escape'),
         'string-replace':lambda strng,x,y: strng.replace(x, y),
        #  Additions above
         'read':read, 'write':lambda x,port=sys.stdout:port.write(to_string(x)),
         'display':lambda x,port=sys.stdout:port.write(x if isa(x,str) else to_string(x))})
        return self

但是,当我尝试使用有问题的racket函数时,我从norvig的lispy repl中得到以下错误:


    % python lispy.py
    Lispy version 2.0
    lispy> (define (ex s)
      (read (open-input-string (string-replace (string-replace s "\'" "\"") "," ""))))
    lispy> (define inputlistsliceexample
      (ex "[0, 0, 1, 0, 1, 1, 0, 1, 0, 0]"))
    AttributeError: 'str' object has no attribute 'next_token'
    lispy>

然后,如果我在ex的定义中不再使用open-input-string,我将得到以下交互:

    % python lispy.py
    Lispy version 2.0
    lispy> (define (exnihilo s)
      (string-replace (string-replace s "\'" "\"") "," ""))    
    lispy> (define inputlistsliceexample
      (exnihilo "[0, 0, 1, 0, 1, 1, 0, 1, 0, 0]"))
    lispy> inputsliceexample
    LookupError: inputsliceexample

我可能过于简化了这个过程,但在我真正深入了解其余的lispy.py之前,我想在这里询问一下,在我添加的内容中,bug是否表面上可见

编辑:

以下是我当前的add_全局列表:


    def add_globals(self):
        "Add some Scheme standard procedures."
        import math, cmath, operator as op
        self.update(vars(math))
        self.update(vars(cmath))
        self.update({
         '+':op.add, '-':op.sub, '*':op.mul, '/':op.div, 'not':op.not_, 
         '>':op.gt, '<':op.lt, '>=':op.ge, '<=':op.le, '=':op.eq, 
         'equal?':op.eq, 'eq?':op.is_, 'length':len, 'cons':cons,
         'car':lambda x:x[0], 'cdr':lambda x:x[1:], 'append':op.add,  
         'list':lambda *x:list(x), 'list?': lambda x:isa(x,list),
         'null?':lambda x:x==[], 'symbol?':lambda x: isa(x, Symbol),
         'boolean?':lambda x: isa(x, bool), 'pair?':is_pair, 
         'port?': lambda x:isa(x,file), 'apply':lambda proc,l: proc(*l), 
         'eval':lambda x: eval(expand(x)), 'load':lambda fn: load(fn), 'call/cc':callcc,
         'open-input-file':open,'close-input-port':lambda p: p.file.close(), 
         'open-output-file':lambda f:open(f,'w'), 'close-output-port':lambda p: p.close(),
         'eof-object?':lambda x:x is eof_object, 'read-char':readchar, 
        #  Additions below
         'string->jsexpr':lambda x: json.loads(x),
         'string-replace':lambda strng,x,y: strng.replace(x, y),
        #  Additions above
         'read':read, 'write':lambda x,port=sys.stdout:port.write(to_string(x)),
         'display':lambda x,port=sys.stdout:port.write(x if isa(x,str) else to_string(x))})
        return self

在lispy repl中,string-replace似乎成功了:


    % python lispy.py
    Lispy version 2.0
    lispy> (string-replace "[['Noth', '<b>ing</b>'], ' in']" "\'" "\"")
    "[[\"Noth\", \"<b>ing</b>\"], \" in\"]"
    lispy>

但是,在lispy.py的末尾,我运行


    if __name__ == '__main__':
        x = eval(parse("""(begin
        (string-replace "[['Noth', '<b>ing</b>'], ' in']" "\'" "\"")
        )
        """
        ))
    
        print x

而不是运行这个(文件就是这样产生的)


    if __name__ == '__main__':
        repl()

程序挂起-当我跟踪它时,我看到有一个无限循环

有什么想法吗?(我认为,这是一个比我的第一个问题更具体的问题……我肯定感觉更接近了……)


Tags: lambdaselfaddclosereadinputstringport
2条回答

不确定为什么要用双引号替换单引号,在给出的示例中不会有任何更改。但是,是的,得出了相同的结论,只是把这个放在这里,让其他人可以看到它是如何写的

(define (ex s) (open-input-string (string-replace s "," "")))
(define inputlistsliceexample (ex "[0, 0, 1, 0, 1, 1, 0, 1, 0, 0]"))
inputlistsliceexample

“[0 0 1 0 1 0 1 0 0 0]”

(define (exnihilo s) (string-replace s "," ""))
(define inputlistsliceexample (exnihilo "[0, 0, 1, 0, 1, 1, 0, 1, 0, 0]"))
inputlistsliceexample

“[0 0 1 0 1 0 1 0 0 0]”

您找不到变量inputsliceexample是有道理的,因为您定义的变量名为inputlistsliceexample。所以你的string-replace工作得很好。我不确定你对open-input-string的问题,但从你发布的链接来看,我觉得read接收文件或端口之类的内容,而open-input-string返回字符串

相关问题 更多 >