Я пытаюсь написать переводчика, но мне не хватает контекста или чего-то еще. Функция, которая должна вызываться для обработки преобразования «+><>
и т. д. предполагается:
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 байтов, а некоторые для чего-то значат.
Изменить: предоставленные инструкции
Аннотация Напишите простой интерпретатор для Brainfk. 1. Введение
Программа Brainfk имеет неявный указатель байта, называемый указателем,
который может свободно перемещаться в массиве 30000 байт, изначально
все установлено на ноль. Сам указатель инициализируется, чтобы указывать на
начало этого массива. Язык программирования Brainfuck состоит из
из восьми команд, каждая из которых представлена в виде одного символа.•
>
Увеличить указатель.
•<
Уменьшить указатель.
•+
Увеличьте байт у указателя.
•-
Уменьшить байт у указателя.
•.
Точка, выводит байт по указателю.
•,
Запятую, введите байт и сохраните его в байте по указателю.
•[
Перейти вперед через совпадение] ЕСЛИ байт в указателе равен нулю.
•]
Перейти назад к совпадению [ЕСЛИ БАЙТ в указателе равен нулю.Например, одна версия «Привет, мир!» Программа в Brainfk есть
++++++++++[>+++++++>++++++++++>+++>+<<<<-] >++.>+.+++++++..+++.>++.<<+++++++++++++++.>. +++.------.--------.>+.>.
2 Требование
2.1 Тестовая программа
Я буду использовать программу для тестирования и оценки вашего кода в пакетном режиме. Поэтому, пожалуйста, проверьте вашу подпись функции. Неспособность бежать
может повлиять на оценку вашего проекта. Функция входа будет все
есть имяinterpret
, И вы можете реализовать столько же других помощников
функционирует так, как вы хотите. В следующих разделах подробно рассматриваются
технические характеристики.2.1.1 C ++ Я бы использовал C ++ 11 (
g++ -std=c++11 ...
) проверить вашу программу. Так что не стесняйтесь использовать некоторые из недавних вкусностей, добавленных в C ++, например,
лямбда-функция, инициализация массива и т. д. Для удобства, пожалуйста,
разделите вашу декларацию и код реализации в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_;
}
Вы должны быть в состоянии вызвать интерпретацию, не создавая ничего, поэтому я не знал другого способа собрать это воедино. Мне еще предстоит реализовать функции прыжка.
Какой смысл в массиве 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 года! (Да!) По крайней мере, кто-то может найти это полезным в будущем …: ^)
Других решений пока нет …