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

Brainf**k - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Рекурсия, ошибка http://www.cyberforum.ru/cpp-beginners/thread239332.html
Здраствуйте! У меня есть одна классическая задачка про Лесенку. Лесенка Лесенкой называется набор кубиков, в котором каждый более верхний слой содержит кубиков меньше, чем предыдущий. Требуется написать программу, вычисляющую число лесенок, которое можно построить из N кубиков. Входные данные Во входном файле input.txt записано натуральное число N (1 ≤ N ≤ 225) – количество кубиков в...
C++ Рекурсия: вычислить количество лесенок, которое можно построить из N кубиков Здраствуйте! У меня есть одна классическая задачка про Лесенку. Лесенка Лесенкой называется набор кубиков, в котором каждый более верхний слой содержит кубиков меньше, чем предыдущий. Требуется написать программу, вычисляющую число лесенок, которое можно построить из N кубиков. Входные данные Во входном файле input.txt записано натуральное число N (1 ≤ N ≤ 225) – количество кубиков в... http://www.cyberforum.ru/cpp-beginners/thread239329.html
C++ Шаблонные функции
Чет не получается написать шаблонную функцию. func.h template <class T> T strnstr (T str, T substr, unsigned int count) { T* str1; T* str2 = substr;
Даны действительные числа C++
1. Даны действительные числа x, y, z Вычислить: а)max(x+y+z, xyz) б)min^2(x+y+z/2,xyz)+1 2) даны x,y,z. вычислить a,b если a=(1+y)*((x+y)/(x^2+4))/e^-x-2 + 1/(x^2+4) b=(1+cos(y-2))/x^4 / 2+sin^2 Z помогите решить пожалуйста.
Visual C++ MFC Picture Control http://www.cyberforum.ru/cpp-beginners/thread239282.html
как сделать что бы Picture Control появлялся только после нажатия кнопки ?
C++ Вычислить арифметическое выражение пожалуйста помогите : Дано натуральное число n. Вычислить подробнее

Показать сообщение отдельно
Nameless One
Эксперт С++
5767 / 3416 / 255
Регистрация: 08.02.2010
Сообщений: 7,441
08.02.2011, 21:37     Brainf**k
Сделал вариант интерпретатора, в котором новые операции определены немного не так, как хотел ТС (но переделать под свои нужды, ИМХО, несложно). Новые операторы вводят не процедуры в их типичном "паскалевском" понимании, а функции, а именно, функции без переменных, которые возвращают значение текущей на момент возврата ячейки. У каждой функции собственные локальные переменные (ячейки). Переменные из внешней области видимости захватывать нельзя. Можно создавать вложенные определения функций. Операторы '(' и ')', соответственно, определяют начало и конец локальной функции. Оператор ':' вызывает функцию, 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 диалектом сабжа

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