BrainFuck只有八条指令:
指令 | 含义 | 解释 |
---|---|---|
> | 指针加一 | 向右移动一个格子 |
< | 指针减一 | 向左移动一个格子 |
+ | 指针指向的字节的值加一 | 给格子里的数字加上 1,擦掉原来的数字再写回去。 |
- | 指针指向的字节的值减一 | 给格子里的数字减去 1 |
. | 输出指针指向的单元内容(ASCII码) | 查当前格子里的数字在 ASCII 表上对应的字母,把它写下来(不,别写在格子里,就写在你买来一直立志想用但是没有用的日记本上吧) |
, | 输入内容到指针指向的单元(ASCII码) | 随便想一个英文字母,查表找到它对应的数字,写到当前格子里 |
[ | 如果指针指向的单元值为零,向后跳转到对应的]指令的次一指令处 | 开始重复「始……终」之间的指令,直到你读到「始」之前盯着的那个格子里的数字变成 0 为止 |
] | 如果指针指向的单元值不为零,向前跳转到对应的[指令的次一指令处 | 如果当前格子里的数字为 0,就跳过,否则回头到「始」那里 |
解释器代码如下:
package interpreter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Test
{
/**
* 测试例子:+++++[>++++++++++<-]>.+++.+++.--.++.-.------.+++++.
* 测试例子:++++++++++[>+++++++++>++++++++>+++++++<<<-]>---.>+.---.-.-.>+.-----.
* 测试例子:++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
* 测试例子:++++++[>++++++[>++++++[>++++++[>+++++[>++++++<-]<-]<-]<-]<-]>++[>+++++[>++++++[>+++++[>------<-]<-]<-]<-]>>+++[>++[>-----<-]<-]>>-.<<<<++++[>++++[>++++[>+++++[>+++++<-]<-]<-]<-]>>>++[>+++++++<-]>.
* 测试例子:>>>><++++++++++[>+++++<-]>-.<<+++++++[>++++++++<-]>.-.>-.++.<--.>-.<.>+.<<<<++[>++++++[>++++++++<-]>+.<++++++[>--------<-]>-<<-]
*/
public static void main(String[] args)
{
List<Integer> finallyResult=new ArrayList<Integer>();//存储最后的解析结果
List<Integer> middleResult=new ArrayList<Integer>();//在计算过程中的结果
List<Integer> middleFlag=new ArrayList<Integer>();//在计算过程中的状态
middleResult.add(0);//过程初始化
middleFlag.add(0);//过程状态初始化
int middleIndex=0;//过程集合的下标
System.out.print("请输入待解析的QQ号:");
Scanner input=new Scanner(System.in);
String temp=input.nextLine();//输入待解析的QQ号
input.close();//关闭输入流
char[] interpreter=temp.toCharArray();//数组解析器
int len=interpreter.length;//输入字符的长度
boolean flag=true;//解析结果的转态,true为成功,false表示失败
for(int i=0;i<len;i++)
{
switch(interpreter[i])
{
case '+':
{ //集合当前下标的数值+1
middleResult.set(middleIndex, middleResult.get(middleIndex)+1);
break;
}
case '-':
{ //集合当前下标的数值-1
middleResult.set(middleIndex, middleResult.get(middleIndex)-1);
break;
}
case '[':
{ //设置循环状态码
middleFlag.set(middleIndex,1);
break;
}
case ']':
{ //循环完了之后没有回到[(状态码为1)或者循环条件出界(小于0),则输入有误
if(middleFlag.get(middleIndex)!=1||middleResult.get(middleIndex)<0)
{
System.out.println("源码错误,我也帮不了你(*^__^*) 嘻嘻……");
flag=false;
}
else
{ //满足循环条件,回到[,相当于循环的回溯
if(middleResult.get(middleIndex)>0)
{
int count=1;
while(count!=0)
{
i--;
if(i<0)
{
i=len;
break;
}
if(interpreter[i]=='[')count--;
else if(interpreter[i]==']')count++;
}
}else{
//取消循环状态码
middleFlag.set(middleIndex,0);
}
}
break;
}
case '.':
{ //存储最后的ASCALL结果
if(middleResult.get(middleIndex)<0)
{
System.out.println("源码解析错误,ASCALL要为整数(*^__^*) 嘻嘻……");
flag=false;
}
else
{
finallyResult.add(middleResult.get(middleIndex));
}
break;
}
case '>':
{ 集合下标右移,如果超出集合范围,扩大集合大小
middleIndex++;
if(middleIndex>=middleResult.size())
{
middleResult.add(0);
middleFlag.add(0);
}
break;
}
case '<':
{ //集合下标左移
middleIndex--;
if(middleIndex<0)
{
System.out.println("左移过界,我也帮不了你(*^__^*) 嘻嘻……");
flag=false;
}
break;
}
default:
{ //转化失败
flag=false;
System.out.println("输入含有其他字符,我也帮不了你(*^__^*) 嘻嘻……");
break;
}
}
if(flag==false)i=len;//跳出循环
}
if(flag==true)
{
System.out.print("解析的结果为:");
//将解析结果以char[]类型输出
for (Integer li : finallyResult)
{
System.out.print((char)(li-0));
}
}
}
}
本人亲测有效,完全属于个人原创,没有参考任何人的代码
测试结果:
测试完毕!!!