Brainfuck переводчик в c проблемы печати

Я пытаюсь написать очень простой интерпретатор мозгового штурма в C, и у меня возникают проблемы, когда я пытаюсь выделить некоторые символы в соответствии с тем, что я понимаю.

Это весь мой код:

#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, который запишет вывод в текстовый файл, и сравните его с предопределенным текстом, проблема в том, что мой текстовый файл выходит в виде двоичного файла, и я не могу понять, почему. Проблема может быть скрыта в том, как я обрабатываю [ а также ] поскольку у меня не было этой проблемы в предыдущих тестах без них

+++++ +++++             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 ответ

Тест неверен при поиске подходящей скобки.

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

Ты устанавливаешь num до 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, поэтому приращение помещает указатель в правильное место.


Вы также можете посмотреть на моего собственного переводчика, который очень похож на ваш. Один из моих рецензентов дает отличное объяснение оптимизации выполнения цикла с помощью таблицы переходов.

Другие вопросы по тегам