自制BrainFuck解析器
相信你们能看懂代码的意思,因为的确很简单,唯一注意的是处理[]指令可以使用栈结构,因为[]指令正好符合栈的性质
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <map>
using namespace std;
class Memory
{
public:
char value;
Memory* left;
Memory* right;
Memory()
{
value = 0;
left = right = NULL;
}
};
class Turing_Machine
{
private:
Memory* ptr;
public:
Turing_Machine()
{
ptr = new Memory();
}
void MoveLeft()
{
if(ptr->left == NULL)
{
ptr->left = new Memory();
ptr->left->right = ptr;
}
ptr = ptr->left;
}
void MoveRight()
{
if(ptr->right == NULL)
{
ptr->right = new Memory();
ptr->right->left = ptr;
}
ptr = ptr->right;
}
char GetValue()
{
return ptr->value;
}
void SetValue(char value)
{
ptr->value = value;
}
~Turing_Machine()
{
while(ptr->left !=NULL)
{
ptr = ptr->left;
}
while(ptr->right != NULL)
{
ptr = ptr->right;
delete ptr->left;
}
delete ptr;
}
};
class BrainFuck
{
private:
Turing_Machine* vm;
char* code;
map<int,int> bind;
public:
BrainFuck(char* raw_code)
{
vm = new Turing_Machine();
code = new char[strlen(raw_code)+1];
stack<int> s;
while(!s.empty()) s.pop();
for(int i = 0;i < strlen(raw_code);i++)
{
switch(raw_code[i])
{
case '[':
s.push(i);
code[i] = raw_code[i];
break;
case ']':
if(s.empty()) throw "[]未匹配\n";
bind[s.top()] = i;
bind[i] = s.top();
s.pop();
code[i] = raw_code[i];
break;
case '+':
case '-':
case '<':
case '>':
case ',':
case '.':
code[i] = raw_code[i];
break;
default:
throw "存在无法识别的指令\n";
}
}
if(!s.empty()) throw "[]未匹配\n";
code[strlen(raw_code)] = '\0';
}
void run()
{
int cur = 0;
while(code[cur]!='\0')
{
switch(code[cur])
{
case '+':
vm->SetValue(vm->GetValue()+1);
break;
case '-':
vm->SetValue(vm->GetValue()-1);
break;
case '>':
vm->MoveRight();
break;
case '<':
vm->MoveLeft();
break;
case '.':
putchar(vm->GetValue());
break;
case ',':
vm->SetValue(getche());
break;
case '[':
if(vm->GetValue() == 0) cur = bind[cur];
break;
case ']':
if(vm->GetValue() != 0) cur = bind[cur];
break;
}
cur++;
}
}
~BrainFuck()
{
delete[] code;
delete vm;
}
};
BrainFuck* bf;
int main()
{
printf("请输入BrainFuck代码:");
char str[65536];
scanf("%s",str);
try
{
bf = new BrainFuck(str);
}
catch(char* msg)
{
printf(msg);
return -1;
}
bf->run();
delete bf;
return 0;
}