Форум программистов, компьютерный форум 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
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
07.02.2011, 15:20     Brainf**k #2
Может, в раздел фриланса перенести? Сомневаюсь, что у кого-то хватит энтузиазма делать за тебя курсовую (или что это такое) ради твоей же повышенной стипендии.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
07.02.2011, 15:29     Brainf**k #3
Так, а в чём же, собственно, заключаются те неприятности, которые вам доставляет факт недавнего окончания вуза вашим преподавателем?
easybudda
07.02.2011, 16:19
  #4

Не по теме:

Цитата Сообщение от silent_1991 Посмотреть сообщение
Так, а в чём же, собственно, заключаются те неприятности, которые вам доставляет факт недавнего окончания вуза вашим преподавателем?
Взятки брать пока боится, приходится по чесноку всё делать...

silent_1991
07.02.2011, 16:22
  #5

Не по теме:

easybudda,

perimetral
1 / 1 / 0
Регистрация: 17.12.2010
Сообщений: 16
07.02.2011, 16:32  [ТС]     Brainf**k #6
Как никак, а easybudda прав. Да и прошу скорей не весь интерпретатор, а хотя бы лирическую теорию о том, как можно реализовать процедуры.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
07.02.2011, 16:37     Brainf**k #7
Да что реализовывать-то? Создаёте список, элементы узла - ID процедуры и строка, содержащая код процедуры. При вызове процедуры ищете в списке процедуру с таким ID и выполняете для следующей ячейки все действия, описанные в процедуре.
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
07.02.2011, 18:53     Brainf**k #8
Цитата Сообщение от perimetral Посмотреть сообщение
Для управления процедурами добавить еще 3 оператора: ( ) :. Оператор ( должен начинать описание процедуры. Т.е. грубо говоря, функции. ID (как бы имя) процедуры есть число и сохраняется в ячейке, на которой стоит каретка при описании процедуры. Оператор ) заканчивает процедуру. Код в процедуре не выполняется при последовательном интерпретировании кода, и вызывается командой :. Команда : читает значение текущей ячейки и вызывает процедуру с ID, указанным в этой ячейке.
Кстати, было бы интересней, если бы у каждой функции (процедуры) было бы свое окружение. Это бы, к примеру, позволяло бы создавать локальные функции
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
07.02.2011, 18:54     Brainf**k #9
Nameless One, Ну по-моему область видимости реализовать не столь просто... Или я ошибаюсь?
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
07.02.2011, 19:02     Brainf**k #10
ForEveR, попробую что-нибудь сделать по этому поводу. Мыслишки есть, если получится, завтра выложу.

Добавлено через 6 минут
Если вкратце - есть структура типа "окружение", которая помимо другой информации хранит массив указателей на структуру "окружение". Этот массив и будет представлять локальные (по отношению к текущему окружению) функции. Так как переменных, по сути, нет (их представляют ячейки), то реализовать такое будет довольно несложно. Функции не будут предоставлять возможности доступа к ячейкам из внешнего окружения.
iama
 Аватар для iama
1249 / 974 / 48
Регистрация: 30.07.2010
Сообщений: 5,297
07.02.2011, 19:06     Brainf**k #11
http://www.mathematik.uni-marburg.de/~schmidtm/bfi.c

Не по теме:

кошмар, сколько народу гуглить не умеет

silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
07.02.2011, 19:19     Brainf**k #12
А не легче ли рекурсией это реализовать? Это будет и естественнее, и проще. Или я чего-то не понял?

Добавлено через 1 минуту
iama, и что? Реализовать исходный интерпретатор не представляет никакой сложности. Здесь интереснее обработку процедур реализовать (дополнение к традиционному брэйнфаку). Так что вы уж повнимательнее тему читайте, прежде чем "народ" обвинять.
iama
 Аватар для iama
1249 / 974 / 48
Регистрация: 30.07.2010
Сообщений: 5,297
07.02.2011, 19:20     Brainf**k #13
вай. пардон.
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
07.02.2011, 19:21     Brainf**k #14
silent_1991, рекурсия там тоже будет
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
07.02.2011, 19:53     Brainf**k #15
Nameless One, а зачем вообще заморачиваться со структурами? При первом проходе просто разделяем код на функции, и разбиваем их по списку, как я уже ранее предлагал. Далее, при вызове, рекурсивно запускаем парсер для строки, хранящейся в нужном узле списка. Поскольку вызывается новых экземпляр парсера, то и память будет выделена новая, и вообще естественным образом будет организована локальная область.
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
07.02.2011, 20:02     Brainf**k #16
silent_1991, хм... Возможно, так будет лучше. В принципе, твое решение будет отличаться от моего только тем, что, у тебя ячейки (переменные) будут представлять собой локальные переменные функции-парсера, а не будут храниться явно в экземляре структуры; т.е. они будут уничтожаться автоматически при возврате из функции, и не придется их вручную "подчищать".
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
07.02.2011, 20:05     Brainf**k #17
Nameless One, именно. Мне просто это решение естественным кажется. Вроде как побочного эффекта от решения другой задачи (т.е. мы решаем задачу собственно реализации функций в брэйнфаке, а побочным эффектом рекурсивного метода является ещё и реализация областей видимости в качестве бонуса).
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
08.02.2011, 21:37     Brainf**k #18
Сделал вариант интерпретатора, в котором новые операции определены немного не так, как хотел ТС (но переделать под свои нужды, ИМХО, несложно). Новые операторы вводят не процедуры в их типичном "паскалевском" понимании, а функции, а именно, функции без переменных, которые возвращают значение текущей на момент возврата ячейки. У каждой функции собственные локальные переменные (ячейки). Переменные из внешней области видимости захватывать нельзя. Можно создавать вложенные определения функций. Операторы '(' и ')', соответственно, определяют начало и конец локальной функции. Оператор ':' вызывает функцию, ID которой задается значением текущей ячейки, и записывает в эту же ячейку возвращаемое значение функции.

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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
 
#define E_NOINP 1
#define E_MEM 2
#define E_OPEN 3
#define E_READ 4
#define E_PAR 5
#define E_LV 6
#define E_LF 7
#define E_LP 8
#define E_INV 9
#define E_RANGE 10
#define E_UND 11
 
#define MAX_CELLS_CNT 512
#define MAX_LOCAL_FUN_CNT 16
#define MAX_PROGRAM_LENGTH 1024
 
typedef struct fun
{
    size_t ID;
        
    struct fun* localFuns[MAX_LOCAL_FUN_CNT];
    size_t localsCnt;
    
    char pExpr[MAX_PROGRAM_LENGTH];
} fun_t;
 
fun_t* newFun(size_t ID, char* expr, char** pRet);
void delFun(fun_t* pFun);
unsigned char eval(fun_t* pFun);
 
#ifdef DEBUG
void printFun(const fun_t* pFun);
void printLocals(unsigned char* pLocals, size_t size);
#endif
 
void errExit(int code, const char* fmt, ...);
 
int main(int argc, char* argv[])
{
    FILE* pInp;
    char  buf[MAX_PROGRAM_LENGTH + 3];
    fun_t* pTopFun;
    unsigned char result;
    char* p;
    
    p = buf;
    *p = '(';
        
    if(argc != 2)
    errExit(E_NOINP, "Usage: %s FILE\n", *argv);
 
    if((pInp = fopen(argv[1], "r")) == NULL)
    errExit(E_OPEN, "Can't open file `%s' to input.\n", argv[1]);
 
    do
    {
    if(p - buf == MAX_PROGRAM_LENGTH)
        errExit(E_LP, "Maximal program length (%u sybmols) was reached.\n", MAX_PROGRAM_LENGTH);
    
    *(++p) = fgetc(pInp);
    }
    while(!isspace(*p) && (*p != EOF) && (*p != '\0'));
 
    if(ferror(pInp))
    errExit(E_READ, "Error reading from file `%s'.\n", argv[1]);
 
    *p = '\0';
    
    printf("Expression: `%s'.\n\n", buf + 1);
    fflush(stdout);
 
    *p++ = ')';
    *p++ = '\0';
    
#ifdef DEBUG
    fputs("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", stderr);
    fputs("Starting parsing...\n\n", stderr);
#endif
 
    pTopFun = newFun(0, buf, NULL);
 
#ifdef DEBUG
    fputs("Parsing is done.\n", stderr);
    fputs("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", stderr);
    fputc('\n', stderr);
    fputs("Starting evaluation...\n\n", stderr);
#endif
 
    result = eval(pTopFun);
    printf("\nThe result is %u.\n\n", result);
    fflush(stdout);
    
#ifdef DEBUG    
    fputs("Evaluation is done.\n", stderr);
#endif
    delFun(pTopFun);
 
    exit(0);
}
 
fun_t* newFun(size_t ID, char* expr, char** pRet)
{
    fun_t* pFun;
    char* p;
    const char* pExpr;
    
    pExpr = expr;
    
    if((pFun = (fun_t*) malloc(sizeof(fun_t))) == NULL)
    errExit(E_MEM, "Can't allocate memory.\n");
    pFun->ID = ID;
     
    memset(pFun->localFuns, 0, sizeof(fun_t*) * MAX_LOCAL_FUN_CNT);
    pFun->localsCnt = 0;
 
    p = pFun->pExpr;
    ++expr;
    
    while(*expr != ')')
    {
    if(*expr == '(')
    {
        if(pFun->localsCnt == MAX_LOCAL_FUN_CNT)
        errExit(E_LF,
            "Local functions maximum was reached"
            " while parsing expression: `%s'.\n", pExpr);
        
        pFun->localFuns[pFun->localsCnt] = newFun(pFun->localsCnt++, expr, &expr);
    }
    else if(strchr("><+-[],.:", *expr) != NULL)
        *p++ = *expr;
    else if(*expr == '\0')
        errExit(E_PAR, "Mismatched parentheses were detected while parsing expression: `%s'.\n", pExpr);
    else
        errExit(E_INV, "Invalid character: `%c'.\n", *expr);
    
    ++expr;
    }
    
#ifdef DEBUG
    printFun(pFun);
#endif
    
    if(pRet)
    *pRet = expr;
    
    return pFun;
}
 
void delFun(fun_t* pFun)
{
    size_t i;
 
    for(i = 0; i < pFun->localsCnt; ++i)
    {
    delFun(pFun->localFuns[i]);
    pFun->localFuns[i] = NULL;
    }
     
    free(pFun);
    pFun = NULL;
}
 
unsigned char eval(fun_t* pFun)
{
    unsigned char locals[MAX_CELLS_CNT];
    unsigned char* pCurrCell;
    char* pCurrOp;
 
    size_t br = 0;
            
#ifdef DEBUG
    fputs("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", stderr);
    fputs("Entering function...\n", stderr);
    printFun(pFun);
#endif
 
    memset(locals, 0, sizeof(unsigned char) * MAX_CELLS_CNT);
    pCurrCell = locals;
    pCurrOp = pFun->pExpr;
    
    while(*pCurrOp != '\0')
    {
 
#ifdef DEBUG
    fprintf(stderr, "Current operation: `%c'.\n", *pCurrOp);
    fprintf(stderr, "Current cells's (%u) value: %u.\n", pCurrCell - locals,
        (size_t) *pCurrCell);
#endif
    switch(*pCurrOp)
    {
    case '+':
        ++(*pCurrCell);
        break;
        
    case '-':
        --(*pCurrCell);
        break;
 
    case '>':
        if(pCurrCell >= locals + MAX_CELLS_CNT - 1)
        errExit(E_RANGE, "The next cell's index is out of range [0..%u].\n", MAX_CELLS_CNT - 1);
        ++pCurrCell;
        break;
 
    case '<':
        if(pCurrCell <= locals)
        errExit(E_RANGE, "The previous cell's index is out of range [0..%u].\n", MAX_CELLS_CNT - 1);
        --pCurrCell;
        break;
 
    case ',':
        *pCurrCell = getchar();
        break;
 
    case '.':
        putchar(*pCurrCell);
        fflush(stdout);
        break;
 
    case ':':
        if(*pCurrCell >= pFun->localsCnt)
        errExit(E_UND, "Function with local ID #%u is undefinded.\n", *pCurrCell);
        
        *pCurrCell = eval(pFun->localFuns[*pCurrCell]);
        break;
        
    case '[':
        if(*pCurrCell == 0)
        {
        ++pCurrOp;
        if(*pCurrOp == '\0')
            errExit(E_PAR, "Mismatched parentheses were found in function's body: `%s'.\n", pFun->pExpr);
        ++br;
        while(br != 0)
        {
            if(*pCurrOp == '[')
            ++br;
            else if(*pCurrOp == ']')
            --br;
            ++pCurrOp;
            if(*pCurrOp == '\0')
            errExit(E_PAR, "Mismatched parentheses were found in function's body: `%s'.\n", pFun->pExpr);
        }
        --pCurrOp;
        }
        break;
 
    case ']':
        if(*pCurrCell != 0)
        {
        --pCurrOp;
        if(pCurrOp < pFun->pExpr)
            errExit(E_PAR, "Mismatched parentheses were found in function's body: `%s'.\n", pFun->pExpr);
        ++br;
        while(br != 0)
        {
            if(*pCurrOp == '[')
            --br;
            else if(*pCurrOp == ']')
            ++br;
            --pCurrOp;
            if(pCurrOp < pFun->pExpr)
            errExit(E_PAR, "Mismatched parentheses were found in function's body: `%s'.\n", pFun->pExpr);
        }
        }
    }
    ++pCurrOp;
    }
    
#ifdef DEBUG
    printLocals(locals, 10);
    fprintf(stderr, "Return value: %u.\n", (size_t) *pCurrCell);
    fputs("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", stderr);
#endif
    return *pCurrCell;
}
 
#ifdef DEBUG
void printFun(const fun_t* pFun)
{
    fprintf(stderr, "Function with local ID #%u:\n", pFun->ID);
    fprintf(stderr, "Body: `%s'\n", pFun->pExpr);
    fprintf(stderr, "Number of local functions: %u.\n\n", pFun->localsCnt);
}
 
void printLocals(unsigned char* pLocals, size_t size)
{
    size_t i;
    
    fprintf(stderr, "The first %u local cells are:\n", size);
    for(i = 0; i < size; ++i)
    fprintf(stderr, "%u ", (size_t) pLocals[i]);
    fputc('\n', stderr);
}
#endif
 
void errExit(int code, const char* fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    exit(code);
}
Интерпретатор получает из командной строки один аргумент - имя файла, содержащее исходный код программы, и читает из него выражение до тех пор, пока не кончится файл или не встретится пробельный символ или '\0'. После чего происходит разбиение выражения на функции и вычисление главной функции.

Ну и программа для теста, которая выводит зацензуренное название языка (прям как в названии темы):
Код
(+++++++++++[>++++++<-]>)(+++++++++++[>++++++++++<-]>)(+++++++[>++++++<-]>):.>+:++++.>+:-------------.++++++++.>+:.<---.>>++:..<<+++++.

Разбор программы
Помимо главной функции, программа содержит три локальных:
  1. ID = 0: `+++++++++++[>++++++<-]>'. Возвращает число 66 (символ `B'). Сначала последовательно 11 раз инкрементируется значение ячейки 0. Потом эта ячейка используется как счетчик цикла, в котором 6 раз инкрементируется значение ячейки 1. Таким образом, 11 * 6 = 66, это значение и возвращается.
  2. ID = 1: `+++++++++++[>++++++++++<-]>'. Возвращает число 110 (символ `n').
  3. ID = 2: `+++++++[>++++++<-]>'. Возвращает число 42 (символ `*').
Тело главной функции: `:.>+:++++.>+:-------------.++++++++.>+:.<---.>>++:..<<+++++.'. Разберем его по шагам:
  1. :. - вызов функции с ID=0 и печать возвращаемого значения (cимвол `B').
  2. >+:++++. - делаем ячейку 1 текущей, инкрементируем ее, вызываем фукнцию 1, которая возвращает 110, увеличиваем это значение до 114 и печатаем символ `r'.
  3. >+:-------------. - переходим к ячейке 2, вызываем функцию 1, уменьшаем возвращаемое значение до 97 и печатаем его (`a').
  4. ++++++++. - увеличиваем текущее значение до 105 и печатаем его (`i').
  5. >+:. - переходим к ячейке 3, вызываем функцию 1, печатаем возвращаемое значение (`n').
  6. <---. - переходим к ячейке 2, уменьшаем ее старое значение (105) до 102 и печатаем его (`f').
  7. >>++:.. - переходим к ячейке 4, увеличиваем ее значение до 2, вызываем функцию с ID=2 и печатаем возвращаемое значение - 42 (символ `*') - два раза.
  8. <<+++++. - переходим к ячейке 2, увеличиваем ее старое значение (102) до 107 и печатаем его (символ `k').


Не по теме:

Кстати, Wikipedia почему-то считает LOLCODE диалектом сабжа

perimetral
1 / 1 / 0
Регистрация: 17.12.2010
Сообщений: 16
08.02.2011, 23:38  [ТС]     Brainf**k #19
Суть в том, что мне лично не нужно, дабы у каждой функции была своя область видимости. Ибо с общей областью видимости программист может передавать параметры (например, в следующих ячейках).
perimetral
1 / 1 / 0
Регистрация: 17.12.2010
Сообщений: 16
08.02.2011, 23:47  [ТС]     Brainf**k #20
Недавно вот тут: http://www.cyberforum.ru/cpp-beginners/thread239337 я просил вас о помощи в реализации интерпретатора Brainf**ck с процедурами. Предложенный вариант не подошел тем, что присутствует ограничение области видимости процедуры. А тем временем я дописал свой интерпретатор, но возникла новая проблема - неизвестная ересь при работе с процедурами. Я сделал парсер отдельной функцией, которую и вызываю при старте программы; при встрече процедуры я вызываю парсер на текст внутри процедуры. Проблема в том, что текст в процедурах не парсится, не знаю, почему. Я бы и сам нашел ошибку, если бы мог ходить отладкой (F10) по коду, но не могу, ибо нужно вводить аргумент в cmd, чего при отладке по F10 нельзя. Кстати, VS2010. Вот код:
Код
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
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;
 
const int MAX = 32767;
 
void parse(char * txt, int pos, int now, int * inf, bool isproc) {
    int len = strlen(txt); int i=0, i3=0, i2=0, toreturn=0; char ** procZ = new char *, * tmp = new char; bool * isp = new bool;
    while (pos<len) {
        switch (txt[pos]) {
        case '<': {
            now++; if (now == MAX) now = 0; pos++;
            break; }
        case '>': {
            now--; if (now == 0) now = MAX; pos++;
            break; }
        case '+': {
            inf[now]++; pos++;
            break; }
        case '-': {
            inf[now]--; pos++;
            break; }
        case ',': {
            inf[now] = getchar(); pos++;
            break; }
        case '.': {
            putchar(inf[now]); pos++;
            break; }
        case '[': {
            if (inf[now] != 0) {
                pos++;
            } else if (inf[now] == 0) {
                i = pos;
                while (txt[i] != ']') { pos++; i++; } }
            break; }
        case ']': {
            if (inf[now] == 0) {
                pos++;
            } else if (inf[now] != 0) {
                i = pos;
                while (txt[i] != '[') { pos--; i--; } }
            break; }
        case ')': {
            if (isproc) {
                pos=len;
            } break; }
        case '(': {
            if (isproc) {
                cout<<"Синтаксическая ошибка на "<<pos+1<<"м символе"; pos=len; break; } else {
            i3 = inf[now];
            procZ[i3] = new char;
            tmp = procZ[i3];
            i = pos; i2 = 0;
            while (txt[i] != ')') {
                tmp[i2] = txt[i]; i2++; i++;
            }
            procZ[i3] = tmp;
            isp[i3] = true;
            pos = i+1;
            break; } }
        case ':': {
            i3 = inf[now];
            tmp = procZ[i3];
            if (isp[i3]) {
                parse(tmp, pos, now, inf, true); } else { cout<<"Попытка вызвать несуществующую процедуру на "<<pos+1<<"м символе";
                pos=len; }
            pos++;
            break; }
        default: {
            pos++; break; }
        } }
}
 
void work(char * txt) {
    int len = strlen(txt), i=0, pos=0, now=100, inf[MAX];
    char ** procZ = new char *; char * tmp = new char;
    while (i<MAX) {
        inf[i] = 0; i++; } i=0;
    parse(txt, pos, now, inf, false);
}
 
int main(int argc, char * argv[])
{
    fstream f = fstream(); setlocale(LC_ALL, "Russian");
    bool towork = true; char * txt = new char;
    if (argc < 2) {
        cout<<"Вы не ввели имя файла";
        towork = false; }
    else if (argc > 2) {
        cout<<"Вы ввели лишний параметр";
        towork = false; }
    if (towork) {
        f.open(argv[1], ios::in);
        f >> txt;
        work(txt);
        cout<<endl<<"Программа завершилась";
        f.close();
    }
    return 0;
}


 Комментарий модератора 
Не нужно плодить темы про одно и то же. Да и ссылку Вы неправильную дали...
Yandex
Объявления
08.02.2011, 23:47     Brainf**k
Ответ Создать тему
Опции темы

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