回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我正在尝试为racket程序编辑Norvig的<a href="https://norvig.com/lispy2.html" rel="nofollow noreferrer">lispy.py</a>模式到python解释器,在该程序中,除了他包含的过程之外,我还使用<code>open-input-string</code>和<code>string-replace</code></p>
<p>看起来我可以将相应的python定义添加到他的<code>add_globals()</code>函数中,如下所示</p>
<pre><code>
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
</code></pre>
<p>但是,当我尝试使用有问题的racket函数时,我从norvig的lispy repl中得到以下错误:</p>
<pre><code>
% 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>
</code></pre>
<p>然后,如果我在<code>ex</code>的定义中不再使用<code>open-input-string</code>,我将得到以下交互:</p>
<pre><code> % 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
</code></pre>
<p>我可能过于简化了这个过程,但在我真正深入了解其余的lispy.py之前,我想在这里询问一下,在我添加的内容中,bug是否表面上可见</p>
<h2>编辑:</h2>
<p>以下是我当前的add_全局列表:</p>
<pre><code>
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
</code></pre>
<p>在lispy repl中,<code>string-replace</code>似乎成功了:</p>
<pre><code>
% python lispy.py
Lispy version 2.0
lispy> (string-replace "[['Noth', '<b>ing</b>'], ' in']" "\'" "\"")
"[[\"Noth\", \"<b>ing</b>\"], \" in\"]"
lispy>
</code></pre>
<p>但是,在lispy.py的末尾,我运行</p>
<pre><code>
if __name__ == '__main__':
x = eval(parse("""(begin
(string-replace "[['Noth', '<b>ing</b>'], ' in']" "\'" "\"")
)
"""
))
print x
</code></pre>
<p>而不是运行这个(文件就是这样产生的)</p>
<pre><code>
if __name__ == '__main__':
repl()
</code></pre>
<p>程序挂起-当我跟踪它时,我看到有一个无限循环</p>
<p>有什么想法吗?(我认为,这是一个比我的第一个问题更具体的问题……我肯定感觉更接近了……)</p>