有人可以解释脑力吗?

时间:2015-11-30 03:51:33

标签: c++ brainfuck

我正在尝试编写一个brainfuck解释器,但我错过了一些背景或某些东西。应该调用以处理“+><>”等转换的函数应该是:

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字节的某个数组上执行相应的命令,以及一些这意味着什么。

编辑:提供说明

  

Abstract为Brainfk写一个简单的解释器。 1简介

     

Brainfk程序有一个隐式字节指针,称为指针,   最初可以在30000字节的数组内自由移动   全部设为零。指针本身被初始化为指向   这个数组的开头。 Brainfuck编程语言包括   八个命令,每个命令都表示为一个字符。

     

>增加指针。
  •<减少指针。
  •+增加指针处的字节   •-减少指针处的字节   •.一个点,在指针处输出字节   •,一个逗号,输入一个字节并将其存储在指针的字节中   •[跳过匹配]如果指针处的字节为零   •]向后跳转到匹配的[除非指针处的字节为零。

     

例如,“Hello,World!”的一个版本Brainfk的程序是

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

2要求

     

2.1测试程序
  我将使用程序批量测试和评分您的代码。所以请仔细检查您的功能签名。未能跑   正确可能会影响您的项目等级。输入功能全部   名字为interpret。你可以实现尽可能多的其他助手   功能如你所愿。以下部分详细说明了   规格。

     

2.1.1 C ++我会使用C ++ 11(g++ -std=c++11 ...)来测试你的程序。所以随意使用一些最近添加到C ++中的好东西,例如,   lambda函数,数组初始化等。为方便起见,请   在bf.hbf.cpp中分隔您的声明和实施代码。   函数签名为std::vector<int> 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 << " ";  

// output: 2  
res = interpret(",.", {2});  
for (auto i : res)  
    std::cout << i << " ";  
return 0;  
}  

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

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.cpp

#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_;
}

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

1 个答案:

答案 0 :(得分:1)

  

如果给函数一个要转换的数组,那么30000字节数组的意义是什么?

假设您有两个数字-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。这很容易实现,可以轻松实现。

,  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解释器将如何按指令逐个粗略地使用上述程序。

*在堆栈中的一个值后面意味着它是堆栈指针现在指向的位置。

我将其中一些分组,以免过长。

  1. ,-tape[index] = input(),堆栈现在为[2*, 0, 0, ...]
  2. >-index += 1,堆栈现在为[2, 0*, 0, ...]
  3. ,-tape[index] = input(),堆栈现在为[2, 3*, 0, ...]
  4. <-index -= 1,堆栈现在为[2*, 3, 0, ...]
  5. [-if (tape[index] == 0) { skipToLoopEnd(); },不跳转(2 == 0为假),堆栈保持不变
  6. >+-堆栈现在为[2, 4*, 0, ...]
  7. <--堆栈现在为[1*, 4, 0, ...]
  8. ]-if (tape[index] != 0) { skipToLoopBegin(); },跳转(1 != 0为真),堆栈保持不变
  9. >+-堆栈现在为[1, 5*, 0, ...]
  10. <--堆栈现在为[0*, 5, 0, ...]
  11. ]-if (tape[index] != 0) { skipToLoopBegin(); }不跳转0 != 0为假),堆栈保持不变
  12. >-index += 1,堆栈现在为[0, 5*, 0, ...]
  13. .-print(tape[index]),打印5

不用说,我没有意识到这个问题来自2015年! (是的!)至少将来有人会觉得有用...:^)