BrainFuck語言ios
極簡的一種圖靈完備的語言,由Urban Müller在1993年創造,由八個指令組成(以下表)。工做機制與圖靈機很是類似,有一條足夠長的紙帶,初始時紙帶上的每一格都是0,有一個數據讀寫頭指向紙帶的初始位置,讀寫頭的行爲由指令指示。c++
指令 | 含義 |
> | 指針向右移動一位 |
< | 指針向左移動一位 |
+ | 指針所指位置的值增長1字節 |
- | 指針所指位置的值減小1字節 |
. | 將指針所指位置的值按ASCII表輸出 |
, | 接受1字節的輸入,存儲在當前指針所指位置 |
[ | 當指針當前處的值爲0時,跳轉到對應]以後;不然,順序執行 |
] | 跳轉回對應[處 |
用經典的Hello World!來舉例說明BrainFuck語言的畫風。ide
++++++++ [ >++++ [ >++ >+++ >+++ >+ <<<<- ] >+ >+ >- >>+ [<] <- ] >>. >---. +++++++..+++. >>. <-. <. +++.------.--------. >>+. >++.
其中的空格、縮進、換行都不影響程序,只是爲了看起來可讀性更強而已。事實上,上述程序徹底能夠寫成這樣:spa
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
編譯器實現(c++)指針
寫了兩個版本,都差很少。第一個直接開始執行,會在從[跳轉到]時向後遍歷,時間稍長;第二個先作一次括號匹配,標記對應的括號位置,內存稍大(事實上,若是括號並很少,能夠用STL的map來動態管理內存)。code
第一個:blog
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 #define MaxCodeLen 1000 //代碼最大長度 7 #define MaxTapeLen 3000 //紙帶最大長度 8 9 char Code[MaxCodeLen]; //代碼 10 char Tape[MaxTapeLen]; //紙帶 11 int St[MaxCodeLen / 2]; //用來匹配括號的棧 12 int top = 0; //棧頂 13 14 int isLegalInstruction(char ch) 15 { 16 int Ret = 0; 17 switch(ch) 18 { 19 case '>' : 20 case '<' : 21 case '+' : 22 case '-' : 23 case '.' : 24 case ',' : 25 case '[' : 26 case ']' : Ret = 1; break; 27 case '\n' : 28 case ' ' : 29 case '\t' : Ret = 2; break; 30 default : break; 31 } 32 return Ret; 33 } 34 35 int main() 36 { 37 freopen("Pro.txt", "r", stdin); 38 char ch; 39 int len = 0; 40 int cur = 0; 41 int i, cnt; 42 char* p = Tape + MaxTapeLen / 2; //爲了方便左右移動,讓紙帶從中間開始 43 while((ch = getchar()) != EOF) 44 { 45 //printf("ch = %c\n", ch); 46 switch(isLegalInstruction(ch)) 47 { 48 case 0 : 49 printf("illegal instruction\n"); 50 return 0; 51 case 1 : 52 Code[len++] = ch; 53 break; 54 default: 55 break; 56 } 57 } 58 //Code[len] = '\0'; 59 //printf("%s\n", Code); 60 freopen("CON", "r", stdin); 61 while(cur < len) 62 { 63 switch(Code[cur]) 64 { 65 case '>' : 66 p++; 67 break; 68 case '<' : 69 p--; 70 break; 71 case '+' : 72 (*p)++; 73 break; 74 case '-' : 75 (*p)--; 76 break; 77 case '.' : 78 printf("%c", *p); 79 break; 80 case ',' : 81 *p = getchar(); 82 break; 83 case '[' : 84 if(*p) 85 { 86 St[top++] = cur; 87 } 88 else 89 { 90 cnt = 0; 91 for(i = cur; i < len; i++) 92 { 93 if(Code[i] == '[') 94 cnt++; 95 if(Code[i] == ']') 96 cnt--; 97 if(!cnt) 98 break; 99 } 100 if(!cnt) 101 { 102 cur = i; 103 } 104 else 105 { 106 printf("parentheses do not match\n"); //左括號比右括號多 107 return 0; 108 } 109 } 110 break; 111 case ']' : 112 cur = St[top - 1] - 1; 113 top--; 114 break; 115 default: 116 break; 117 } 118 cur++; 119 if(top < 0) 120 { 121 printf("parentheses do not match\n"); //右括號比左括號多 122 return 0; 123 } 124 } 125 printf("\n"); 126 return 0; 127 }
第二個:ip
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 #define MaxCodeLen 1000 //代碼最大長度 7 #define MaxTapeLen 3000 //紙帶最大長度 8 9 char Code[MaxCodeLen]; //代碼 10 char Tape[MaxTapeLen]; //紙帶 11 int St[MaxCodeLen / 2]; //用來匹配括號的棧 12 int top = 0; //棧頂 13 int Match[MaxCodeLen]; //括號匹配 14 15 int isLegalInstruction(char ch) 16 { 17 int Ret = 0; 18 switch(ch) 19 { 20 case '>' : 21 case '<' : 22 case '+' : 23 case '-' : 24 case '.' : 25 case ',' : 26 case '[' : 27 case ']' : Ret = 1; break; 28 case '\n' : 29 case ' ' : 30 case '\t' : Ret = 2; break; 31 default : break; 32 } 33 return Ret; 34 } 35 36 int main() 37 { 38 freopen("Pro.txt", "r", stdin); 39 char ch; 40 int len = 0; 41 int cur, i, cnt; 42 char* p = Tape + MaxTapeLen / 2; //爲了方便左右移動,讓紙帶從中間開始 43 while((ch = getchar()) != EOF) 44 { 45 //printf("ch = %c\n", ch); 46 switch(isLegalInstruction(ch)) 47 { 48 case 0 : 49 printf("illegal instruction\n"); 50 return 0; 51 case 1 : 52 Code[len++] = ch; 53 break; 54 default: 55 break; 56 } 57 } 58 //Code[len] = '\0'; 59 //printf("%s\n", Code); 60 for(i = 0; i < len; i++) 61 { 62 if(Code[i] == '[') 63 { 64 St[top++] = i; 65 } 66 else if(Code[i] == ']') 67 { 68 if(top <= 0) 69 { 70 printf("parentheses do not match\n"); //右括號比左括號多 71 return 0; 72 } 73 Match[i] = St[top - 1]; 74 Match[St[top - 1]] = i; 75 top--; 76 } 77 } 78 if(top > 0) 79 { 80 printf("parentheses do not match\n"); //左括號比右括號多 81 return 0; 82 } 83 freopen("CON", "r", stdin); 84 cur = 0; 85 while(cur < len) 86 { 87 switch(Code[cur]) 88 { 89 case '>' : 90 p++; 91 break; 92 case '<' : 93 p--; 94 break; 95 case '+' : 96 (*p)++; 97 break; 98 case '-' : 99 (*p)--; 100 break; 101 case '.' : 102 printf("%c", *p); 103 break; 104 case ',' : 105 *p = getchar(); 106 break; 107 case '[' : 108 if(!(*p)) 109 { 110 cur = Match[cur]; 111 } 112 break; 113 case ']' : 114 cur = Match[cur] - 1; 115 break; 116 default: 117 break; 118 } 119 cur++; 120 } 121 printf("\n"); 122 return 0; 123 }
【也許有空了能夠琢磨一下寫個界面hhh】內存