我正在尝试用 C 编写一个 brainf*ck Interpreter。 当前指针、数组和数组的长度在结构中给出。
解释器方法接收指向数组结构的指针和 brainf*ck 指令作为字符串。如果指令有效,该方法可能返回 1,否则返回 0。
我不明白这个错误可能发生在哪里。也许是一个错误的指针。
struct Array {
size_t array_len;
uint8_t* array;
uint8_t* cur;
};
int brainfuckInterpreter(struct Array* state, const char* program) {
uint8_t ptr = *(state->cur); // loading the the pointer for the array
char prog_curr;
uint8_t brk_count; // bracket-counter for jump commands
uint8_t i = 0; // counter for the array
while( i < state->array_len-1){
if(ptr > state->array_len || ptr < 0){ // check if the array-pointer is within the array
return 0;
}
prog_curr = *(program+i++); // Loading the next command of the string program
switch (prog_curr){
case '.': putchar( state->array[ptr]); break;
case '+': {state->array[ptr]++;} break;
case '-': {state->array[ptr]--;} break;
case '>': {
if(ptr >= state->array_len){
return 0;
}else {
ptr++;
}
} break;
case '<': {
if(ptr < 0){
return 0;
}else {
ptr--;
} break;
}
case '[': {
if( state->array[ptr] == 0 ){
brk_count = 0;
prog_curr = *(program + ptr);
do{
if(prog_curr == '['){brk_count++;};
if(prog_curr == ']'){brk_count--;};
if(brk_count != 0){
ptr++;
prog_curr = *(program+ptr);
}
} while (brk_count != 0);
}else{
ptr++;
}
} break;
case ']': {
if(state->array[ptr] == 0){
brk_count = 0;
prog_curr = *(program + ptr);
do{
if(prog_curr == '['){brk_count--;};
if(prog_curr == ']'){brk_count++;};
if( brk_count != 0){
ptr--;
prog_curr = *(program + ptr);
}
} while (brk_count != 0);
}else{
ptr++;
}
} break;
default: {ptr++;} break; // all other characters are getting ignored
}
}
return 1;
}
几个问题。
你把 ptr 和 i 搞混了;您开始使用 ptr 作为数组中的位置,而 i 作为程序中的位置,但是您将 i 与 state->array_len 而不是程序的长度进行比较,然后在以后的括号处理代码中使用“ptr”对于两个变量。
(此外,您的括号代码假定程序索引仍指向当前命令,但您在循环开始时自动递增 i。)
(并且非命令的默认操作不应该增加 ptr 或 i 因为你非常合理地不把它留给单独的命令来做,所以明确地这样做会使它发生两次。与“其他”情况相同括号处理,至少如果您更改为在最外层 while 循环的末尾递增 i 或使其成为 for 循环。)
另外:通过将 ptr 和 i 以及 *cur 定义为字节,您可以将 brainfuck 数组和程序的长度限制为 256 字节,这是不行的。副手我建议 16 兆字节作为一个很好的限制。
你的']'代码中的测试也颠倒了(应该跳回 NONzero),并且你有一个 off-by-one 检查“ptr > state->array_len”而不是“ptr >= state->array_len “.