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