我正在尝试编写一个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.h
和bf.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_;
}
你应该能够在没有实例化任何东西的情况下调用解释,所以我不知道将其组合在一起的另一种方法。我还没有实现跳转功能。
答案 0 :(得分:1)
如果给函数一个要转换的数组,那么30000字节数组的意义是什么?
假设您有两个数字-2和5-并希望Brainfuck程序打印它们的和。
当您只能操作当前单元格中的值并“选择”当前单元格时,该怎么办?当然,您有时会需要一些临时内存。
为了在两个单独的单元格中具有两个值,为加法做准备,这是您可以做的:
,>,
如果用户输入2
和3
(十进制,而不是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解释器将如何按指令逐个粗略地使用上述程序。
*
在堆栈中的一个值后面意味着它是堆栈指针现在指向的位置。
我将其中一些分组,以免过长。
,
-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年! (是的!)至少将来有人会觉得有用...:^)