Форум программистов, компьютерный форум CyberForum.ru

Brainf**k - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.64
perimetral
1 / 1 / 0
Регистрация: 17.12.2010
Сообщений: 16
07.02.2011, 12:48     Brainf**k #1
Народ, суть проблемы такова: наш препод по программированию сам только только окончил вуз, и, к сожалению, это дотавляет неприятности. Вот какое задание к лабораторной он дал:
"Как известно, язык Brainf**k есть интерпретируемый язык программирования с 8ю операциями: > < + - [ ] , .. Задача состоит в написании интерпретатора для него на C++.". Почитать о нем лучше всего на Вики. Это вроде не сложно. В крайнем случае можно взять известный интерпретатор на JS и переписать структуру под C++. Но для 5ки, нужно еще кое-что добавить: необходимо описать процедуры языка. Для управления процедурами добавить еще 3 оператора: ( ) :. Оператор ( должен начинать описание процедуры. Т.е. грубо говоря, функции. ID (как бы имя) процедуры есть число и сохраняется в ячейке, на которой стоит каретка при описании процедуры. Оператор ) заканчивает процедуру. Код в процедуре не выполняется при последовательном интерпретировании кода, и вызывается командой :. Команда : читает значение текущей ячейки и вызывает процедуру с ID, указанным в этой ячейке. Для работы в процедуру передается следующая ячейка (т.е. в самой процедуре каретка изначально будет стоять на ячейке n+1, где n - ячейка , хранящая ID процедуры).
Народ, пожалуйста, помогите, для повышенной стипендии как раз не хватает этого зачета на 5, буду очень благодарен! Сдавать в пятницу, так что, думаю, время есть. Собственно, нужен полный интерпретатор + новые 3 команды.
Пример кода с ними:
Код
>>>+(+++)<<<,>+:<[>>+<<-].
Тут мы в 3й ячейке (если отчет с 0 вести) ставим ID процедуры = 1, потом описываем процедуру (она трижды инкрементирует рабочую ячейку), потом возвращаемся в ячейку 0, вводим в нее символ, в ячейке 1 ставим единицу и вызываем процедуру с этим ID. Т.к. рабочая ячейка нашей процедуры в данном случае - ячейка 2, потому мы возвращаемся в ячейку 0 и переносим из нее значение в ячейку 2, прибавляя то, что там уже есть. Выводим результат - наш символ + 3 по ASCII.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
09.02.2011, 05:06     Brainf**k #21
Цитата Сообщение от perimetral Посмотреть сообщение
Я бы и сам нашел ошибку, если бы мог ходить отладкой (F10) по коду, но не могу, ибо нужно вводить аргумент в cmd, чего при отладке по F10 нельзя. Кстати, VS2010.
Студии под рукой нет, но, если не ошибаюсь, можно в свойствах проекта в разделе "Отладка" (Debugging) указать аргументы командной строки для отладки.

Добавлено через 7 минут
Вот, собственно, руководство, как это сделать: http://msdn.microsoft.com/ru-ru/libr...(v=VS.90).aspx.
И вопрос: что мешает, если уж ты не разобрался, как задать аргументы командной строки при отладке, "зашить" необходимое значение в коде самой программы, например, вот так:
C++
1
2
3
4
int main(/*int argc, char* argv[]*/)
{
    ifstream f = ifstream("testfile.bf");
    // ... и так далее
Добавлено через 9 минут
Цитата Сообщение от perimetral Посмотреть сообщение
Предложенный вариант не подошел тем, что присутствует ограничение области видимости процедуры
Если не хочешь доделывать свой вариант, можно легко переделать мой, чтобы он удовлетворял твоим требованиям. Нужно всего лишь заменить дерево fun_t на глобальный массив и немного изменить функции разбора и вычисления.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
09.02.2011, 14:07     Brainf**k #22
perimetral, проверяйте, то, что вам надо?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
 
void interpret(std::string &, const char *, const char *);
int interpret_helper(std::string &, const char *, const char *, int *, int);
 
int main(int argc, char *argv[])
{
    setlocale(LC_ALL, "Rus");
    
    if (argc != 4)
    {
        std::cerr << "Программа должна быть запущенна в виде" << std::endl
                  << "имя_программы имя_входного_файла имя_файла_входных_данных имя_файла_выходных_данных" << std::endl;
 
        exit(1);
    }
    
    std::ifstream fprog(argv[1]);
 
    std::string prog;
    std::string temp;
 
    while (fprog >> temp)
        prog += temp;
 
    fprog.close();
 
    interpret(prog, argv[2], argv[3]);
 
    return 0;
}
 
void interpret(std::string &prog, const char *input_file_name, const char *output_file_name)
{
    int memory[2048] = {0};
    
    interpret_helper(prog, input_file_name, output_file_name, memory, 0);
}
 
int interpret_helper(std::string &prog, const char *input_file_name, const char *output_file_name, int *memory, int index)
{
    std::ifstream input(input_file_name);
    std::ofstream output(output_file_name);
 
    std::vector< int > loop(prog.size());
 
    int level = 1;
 
    for (size_t i = 0; i < prog.size(); ++i)
    {
        loop[i] = 0;
 
        if (prog[i] == '[')
            loop[i] = level++;
        else
        {
            if (prog[i] == ']')
                loop[i] = --level;
        }
    }
 
    std::map< int, std::string > funcs;
 
    int start_index = index;
 
    for (size_t i = 0; i < prog.size(); ++i)
    {
        switch (prog[i])
        {
        case '>':
            ++index;
 
            break;
        case '<':
            --index;
 
            break;
        case '+':
            ++memory[index];
 
            break;
        case '-':
            --memory[index];
            break;
        case '.':
            output << memory[index];
 
            break;
        case ',':
            input >> memory[index];
 
            break;
        case '[':
            if (memory[index] == 0)
            {
                level = loop[i++];
 
                while (loop[i] != level)
                    ++i;
            }
 
            break;
        case ']':
            if (memory[index] != 0)
            {
                level = loop[i--];
 
                while (loop[i] != level)
                    --i;
 
                --i;
            }
 
            break;
        case '(':
        {
            size_t left_bracket, right_bracket;
 
            left_bracket = i + 1;
 
            while (prog[++i] != ')');
 
            right_bracket = i;
 
            std::string func;
 
            for (size_t k = left_bracket; k < right_bracket; ++k)
                func += prog[k];
 
            funcs.insert(std::make_pair(memory[index], func));
 
            break;
        }
        case ':':
            index = interpret_helper(funcs[memory[index]], input_file_name, output_file_name, memory, index + 1);
            
            break;
        default:
            std::cerr << "Синтаксическая ошибка в позиции " << i << std::endl;
 
            exit(1);
        }
    }
 
    return start_index - 1;
}
perimetral
1 / 1 / 0
Регистрация: 17.12.2010
Сообщений: 16
09.02.2011, 18:52  [ТС]     Brainf**k #23
silent_1991, Спасибо, работает как надо, осталось разобраться с vector, ибо мне преподу еще пояснять как это все работает. Но все равно благодарен =)
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
09.02.2011, 20:03     Brainf**k #24
perimetral, это я ещё по минимуму STL использовал. Выдирание функции из текста программы сделано полностью вручную, можно было всё это стандартными алгоритмами провернуть.
Yandex
Объявления
09.02.2011, 20:03     Brainf**k
Ответ Создать тему
Опции темы

Текущее время: 19:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru