在cmp,Python中超出了最大递归深度

时间:2015-08-24 01:10:53

标签: python recursion runtime-error interpreter

我是Python的初级程序员,试图通过构建BF解释器来练习。但是,它不适用于Hello,World!程序:

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.

给出RuntimeError: maximum recursion depth exceeded in cmp。我的代码如下。

import sys

script, file = sys.argv


tape, tapeslct, cmdslct = [0], 0, 0
code = open(file)
program = filter(lambda x: x in ['.', ',', '[', ']', '<', '>', '+', '-'], code.read())
print(str(program))
program = list(program)

def execute(cmd):
    global tape
    global tapeslct
    global cmdslct
    if cmd == "+":
        tape[tapeslct] += 1
    if cmd == "-":
        tape[tapeslct] -= 1
    if cmd == ">":
        tapeslct += 1
        if tapeslct == len(tape):
            tape.append(0)
    if cmd == "<":
        tapeslct -= 1
    if cmd == ".":
        print(chr(tape[tapeslct]))
    if cmd == ",":
        tape[tapeslct] = ord(input())
    if cmd == "[":
        if tape[tapeslct] >= 1:
            loopend = 0
            testfor = cmdslct
            while loopend == 0:
                testfor += 1
                if program[testfor] == "]" and tape[tapeslct] >= 0:
                    testfor = cmdslct + 1
                    execute(program[testfor])
                elif program[testfor] == "]" and tape[tapeslct] == 0:
                    loopend = 1
                    cmdslct = testfor + 1
                else:
                    execute(program[testfor])
        else:
            while loopend == 0:
                testfor += 1
                if program[testfor] == "]":
                    loopend = 1
while len(program) > cmdslct:
    execute(program[cmdslct])
    cmdslct += 1

lambda代码段取自Python中的另一个BF解释器,找到here

我很遗憾,很遗憾。

1 个答案:

答案 0 :(得分:1)

从我看到的情况来看,您的[]实施方式很糟糕。在子程序中,您开始使用不同的指令指针(testfor而不是cmdslct);但当你点击另一个[时,你会从cmdslct而不是当前的testfor开始下一个循环,这会使嵌套循环无法进行。

我建议你不要把你的循环视为特殊的。当[到来时,只需将当前位置推入堆栈;当]到来时,弹出它,然后根据磁带跳转或忽略。这样,你甚至不需要递归。

或者,将指令指针(而不是cmd)传递给递归。

if cmd == "[":
    # remember loop start
    stack.append(cmdslct)
    if tape[tapeslct] == 0:
        # end of loop; find the matching loop end
        loops = 1
        while not (program[cmdslct] == ']' and loops > 0):
            cmdslct += 1
            if program[cmdslct] == '[':
                loops += 1
            elif program[cmdslct] == ']':
                loops -= 1
if cmd == ']':
    if tape[tapeslct] != 0:
        # jump back
        cmdslct = stack[-1]
    else:
        # forget about this loop and move on
        stack.pop()