在打印麻烦时使用Brainfuck解释器

时间:2015-05-08 14:12:13

标签: c printing interpreter brainfuck

我正在尝试用C语言编写一个非常简单的brainfuck解释器,并且在尝试按照我的理解来打印某些字符时遇到了问题。

这是我的全部代码:

#include <stdio.h>

int bla(char tabukaz[30000], int ukaz, int num) {
    int sum = 0;
    int index = ukaz;
    while (sum > -1) {
        index -= num;
        if (tabukaz[index] == ']')
          sum += num;
        else if (tabukaz[index] == '[')
          sum -= num;
    }   
    return index;
}

int main () {
    int tab[30000];
    int tabukaz[30000];
    int c; 
    int i = 0; int ukaz = 0;
    unsigned char ch;
    for (int i = 0; i < 30000; i++) {
        tab[i] = 0;
        tabukaz[i] = 0;
    }
    while ((c=getchar()) != EOF) {
        ch = (unsigned char)c;
        if (ch == '>' || ch == '<' || ch == '+' || ch == '-' || ch == '.' || ch == '[' || ch == ']')
        {
            tabukaz[ukaz] = ch;
        }

        switch (ch) {
            case '>': i++; break;
            case '<': i--; break;
            case '+': tab[i]++;break;
            case '-': tab[i]--; break;
            case '.': putchar(tab[i]); break;
            case '[':
                if (tab[i]==0) {
                    ukaz = bla(tabukaz, ukaz, -1);
                }
                break;
            case ']':
                if (tab[i]!=0) {
                    ukaz = bla(tabukaz, ukaz, 1);
                }    
                break;
            default:
                break;
        }
        ukaz++;
    }
    return 0;
}

这是有问题的输入(我试图避免实际输入中的其他文本(请记住这里的所有内容都是输入的一部分,甚至是不必要的文本)我们提供了一个make文件,它将写入输出到文本文件,并将其与预定义的文本进行比较,问题是我的文本文件作为二进制文件出来,我无法弄清楚原因。问题可能隐藏在我如何处理[和{{ 1}}因为我没有在没有它们的早期测试中没有这个问题

]

作为某人的建议,我这样做了:

+++++ +++++             initialize counter (cell #0) to 10
[                       use loop to set 70/100/30/10
    > +++++ ++              add  7 to cell #1
    > +++++ +++++           add 10 to cell #2
    > +++                   add  3 to cell #3
    > +                     add  1 to cell #4
<<<< -                  decrement counter (cell #0)
]
> ++ .                  print 'H'
> + .                   print 'e'
+++++ ++ .              print 'l'
.                       print 'l'
+++ .                   print 'o'
> ++ .                  print ' '
<< +++++ +++++ +++++ .  print 'W'
> .                     print 'o'
+++ .                   print 'r'
----- - .               print 'l'
----- --- .             print 'd'
> + .                   print '!'
> .                     print '\n'

然而问题现在扩展到之前的测试,因为它甚至将它们输出为二进制文件,我认为while ((c=getchar())!=EOF) { ch = (unsigned char)c; if (ch == '>' || ch == '<' || ch == '+' || ch == '-' || ch == '.' || ch == '[' || ch == ']') { tabukaz[ukaz]=ch; stukaz++; } } while (stukaz>0) { switch (tabukaz[ukaz]) { case '>': i++; break; case '<': i--; break; case '+': if(tab[i]==255) tab[i] = 0; else tab[i]++; break; case '-': if (tab[i]==0) tab[i] = 255; else tab[i]--; break; case '.': printf ("%c", tab[i]); break; case '[': if (tab[i]==0) { ukaz = bla(tabukaz, ukaz, -1); } break; case ']': if (tab[i]!=0) { ukaz = bla(tabukaz, ukaz, 1); } break; default: break; } stukaz--; ukaz++; } [代码有问题,因此它没有正确地增加字段打印不需要的字符,只有当它周围放置另一个循环时,如何将它扩展到没有它们的测试我不知道。

编辑:上面循环的问题不是while循环没有进入低谷,问题是它永远不会进入交换机,任何解决方案吗?

1 个答案:

答案 0 :(得分:0)

扫描匹配的支架时测试错误。

 while (sum > -1) {
        index -= num;
        if (tabukaz[index] == ']')
          sum += num;
        else if (tabukaz[index] == '[')
          sum -= num;
    }   

您将num设置为1以进行向后扫描,但将-1设置为-1以进行正向扫描。

    case '[':
        if (tab[i]==0) {
            ukaz = bla(tabukaz, ukaz, -1);
        }
        break;
    case ']':
        if (tab[i]!=0) {
            ukaz = bla(tabukaz, ukaz, 1);
        }    
        break;

所以测试应该是(sum != 0),所以当括号从任一方向平衡时它会停止。当然,sum初始化为0,因此我建议使用do { ... } while();循环,以便测试结束。

另外,请记住,您在循环结束时递增指令指针。

        ukaz++;

因此您可能希望将指针设置为bla(...) - 1,因此增量会将指针放在正确的位置。

您可能还想看my own brainfuck interpreter,这与您的非常相似。我的一位评论员给出了使用跳转表优化循环执行的出色解释。