我正在尝试编写一个脑残的解释器,但我缺少一些上下文或其他东西。应该被调用来处理“+><>”等转换的函数应该是:

std::vector<int> Interpreter::interpret(const std::string &src_,
    const std::vector<int> & input_)

程序测试如下:
    int main()
{
std::vector<int> res;
// output: 1
res = interpret("+.");
for (auto i : res)
std::cout << i << " ";
2
// output: 2
res = interpret(",.", {2});
for (auto i : res)
std::cout << i << " ";
return 0;
}

http://www.muppetlabs.com/~breadbox/bf/

我真的不明白这是在做什么。我看过其他视频,但它只是没有意义。有人可以解释一下目标吗?

如果函数被赋予一个要转换的数组,那么 30000 字节数组的意义何在?

编辑:
我应该编写 C++ 代码,将字符转换为 Brainfuck 命令的字符,并且他们应该在一些 30000 字节的数组上执行相应的命令,以及这意味着什么。

编辑:提供说明



编辑:到目前为止我所拥有的:

BFK.h
#pragma once
#include <vector>
#include <iostream>

using namespace std;


char arr[30000];
char* p = arr;

void incPtr();

void decPtr();

void incByte();

void decByte();

void printByte();

void setByte();

void jumpF();

void jumpB();

std::vector<int> interpret(const std::string &src,
    const std::vector<int> & input = {});

BFK文件
#include "BFK.h"

void incPtr() {
    p++;
}

void decPtr() {
    p--;
}

void incByte() {
    (*p)++;
}

void decByte() {
    (*p)--;
}

void printByte() {
    std::cout << *p;
}

void setByte() {
    std::cin >> *p;
}

void jumpF() {
    if (*p == 0) {

    }
}

void jumpB() {

}


std::vector<int> interpret(const std::string &src_,
    const std::vector<int> & input_){
    int i = 0;
    int max = src_.size();
    while (i < max) {
        switch (src_[i]) {
        case '>':
            incPtr();
            break;
        case '<':
            decPtr();
            break;
        case '+':
            incByte();
            break;
        case '-':
            decByte();
            break;
        case '.':
            printByte();
            break;
        case ',':
            setByte();
            break;
        case '[':
            jumpF();
            break;
        case ']':
            jumpB();
            break;
        }
    }

    return input_;
}

您应该能够在不实例化任何内容的情况下调用解释,所以我不知道将它们组合在一起的另一种方法。我还没有实现跳转功能。

最佳答案



想象一下,您有两个数字 - 2 和 5 - 并希望您的 Brainfuck 程序打印它们的总和。

当您只能操作当前单元格中的值并“选择”哪个单元格是当前单元格时,您会怎么做?当然,您有时需要一些临时内存。

为了在两个单独的单元格中有两个值,为添加做准备,您可以这样做:

,>,

如果用户输入 23(十进制,而不是 ascii),那么 Brainfuck 程序存储器或磁带的前两个字节将如下所示:
[2, 3, 0, 0, ...]
//  ^ This is where our tape pointer is now. We incremented it with `>`

够了,现在添加怎么样?一个解决方案是使用 Brainfuck 循环。

让我们添加两个自然整数,除了递增和递减值外,什么都不做:
int a = 2, b = 3

while (a != 0)
{
    b += 1
    a -= 1
}

基本上,我们递减第一个值直到它达到零,随着这个递减,我们递增第二个值。随着时间的推移,这将显示:
a = 2, b = 3
a = 1, b = 4
a = 0, b = 5
a == 0, break

因此,我们确实得到了 2 + 3 = 5 。这很简单,可以在 Brainfuck 中实现。
,  Get value for first cell (a)
>, Get value for second cell (b)
<  Move back to a
[  Loop until a == 0
    >+ Decrement b
    <- Increment a
    We are still at a at this point, so everything is alright
]  Loop again if a != 0
>. Print the final result (sum of a plus b)

...所有这些都是为了演示如何使用 Brainfuck 的磁带存储器来做实际的事情。

我相信很多 Brainfuck 程序将磁带作为堆栈进行操作。有趣的是,您实际上并不需要了解 Brainfuck 程序采用的以可用方式临时存储值的技术。

让我们看看 Brainfuck 解释器如何粗略地处理上述程序,逐条指令。
* 在堆栈中的值之后意味着它是堆栈指针现在指向的位置。

我会将其中的一些分组,以免时间过长。
  • , - tape[index] = input() ,堆栈现在是 [2*, 0, 0, ...]
  • > - index += 1 ,堆栈现在是 [2, 0*, 0, ...]
  • , - tape[index] = input() ,堆栈现在是 [2, 3*, 0, ...]
  • < - index -= 1 ,堆栈现在是 [2*, 3, 0, ...]
  • [ - if (tape[index] == 0) { skipToLoopEnd(); } ,不跳转( 2 == 0 为假),堆栈保持不变
  • >+ - 堆栈现在是 [2, 4*, 0, ...]
  • <- - 堆栈现在是 [1*, 4, 0, ...]
  • ] - if (tape[index] != 0) { skipToLoopBegin(); } ,跳转( 1 != 0 为真),堆栈左侧相同
  • >+ - 堆栈现在是 [1, 5*, 0, ...]
  • <- - 堆栈现在是 [0*, 5, 0, ...]
  • ] - if (tape[index] != 0) { skipToLoopBegin(); } , 不跳转 ( 0 != 0 为假),堆栈保持不变
  • > - index += 1 ,堆栈现在是 [0, 5*, 0, ...]
  • . - print(tape[index]) ,打印 5 !

  • 不用说,我没有意识到这个问题是 2015 年的! (是的!)至少有人将来可能会发现这很有用...... :^)

    关于c++ - 有人可以解释一下脑残吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33991173/

    10-10 13:24