我正在尝试编写一个脑残的解释器,但我缺少一些上下文或其他东西。应该被调用来处理“+><>
”等转换的函数应该是:
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 程序打印它们的总和。
当您只能操作当前单元格中的值并“选择”哪个单元格是当前单元格时,您会怎么做?当然,您有时需要一些临时内存。
为了在两个单独的单元格中有两个值,为添加做准备,您可以这样做:
,>,
如果用户输入
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
。这很简单,可以在 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/