3

本文档之后,我正在为Brainfuck编写一个解释器,在我的实现中需要转换一个字符串,例如:

',>,<[>[->+>+<<]>>[-<<+>>]<<<-]>>.'

进入如下指令列表:

[',', '>', ',', '<', [ '>', [ '-', '>', '+', '>', '+', '<', '<', ], '>', '>', [ '-', '<', '<', '+', '>', '>', ] '<', '<', '<', '-' ], '>', '>', '.']

或者,减去符号:

[ ... [...] ... [...] ... ]

现在我正在递归地解决这个问题,使用 deque 和 popleft() 一次遍历字符串一个符号,但我觉得我应该一次将它分解为子数组。

你将如何以 Pythonic 的方式解决这个问题?

(出于速度原因排除正则表达式)

4

3 回答 3

1

它不完全是“Pythonic 方式”,但是....我找到了使用递归和生成器解决问题的方法

s = ',>,<[>[->+>+<<]>>[-<<+>>]<<<-]>>.'

def brainfuck2list(brainfuck):
  while brainfuck:               #if list is empty then finish
    e = brainfuck.pop(0)
    if e not in ("[","]"):
      yield e
    elif e == "[":
      yield list(brainfuck2list(brainfuck))
    else:
      break

[_ for _ in brainfuck2list(list(s))]

你得到以下输出

[
  ',', '>', ',', '<', 
  [
    '>', 
    [
      '-', '>', '+', '>', '+', '<', '<'
    ]
    , '>', '>', 
    [
      '-','<', '<', '+', '>', '>'
    ], 
    '<', '<', '<', '-'
  ]
  , '>', '>', '.'
]
于 2015-05-10T02:29:59.557 回答
1

出于好奇,这是我使用递归的工作解决方案:

def tokenize(code):
  instructions = deque()

  if len(code) > 0:
    while len(code) > 0:
      if code[0] is "[":
        code.popleft()

        group = deque()
        r = 0

        while r > -1 and len(code) > 0:
          if code[0] is '[':
            group.append(code.popleft())
            r += 1

          elif code[0] is ']':
            if r is 0: 
              code.popleft()

            else:
              group.append(code.popleft())

            r -= 1

          else:
            group.append(code.popleft())

        instructions.append(tokenize(group))

      else:
        instructions.append(code.popleft())

    return instructions

else:
  return instructions
于 2015-05-10T03:08:09.270 回答
0

我快到了:

s=',>,<[>[->+>+<<]>>[-<<+>>]<<<-]>>.'

x = eval('["' + s.replace('[','",["').replace(']','"],"') + '"]')

这会产生:

[',>,<', ['>', ['->+>+<<'], '>>', ['-<<+>>'], '<<<-'], '>>.']

这不是您想要的,但您也可以迭代字符串。

ast.literal_eval如果您担心 eval 的安全性,请使用。

更新:使用正则表达式,我做到了:

import re
s=',>,<[>[->+>+<<]>>[-<<+>>]<<<-]>>.'
everything = re.compile("([^\]\[])")
y = eval('[' + everything.sub(r'"\1",',s).replace(",]","]").replace(']"','],"') + ']')

这变成:

[',', '>', ',', '<', ['>', ['-', '>', '+', '>', '+', '<', '<'], '>', '>', ['-', '<', '<', '+', '>', '>'], '<', '<', '<', '-'], '>', '>', '.']
于 2015-05-10T00:58:31.967 回答