Его Правительские Звания
134 / 115 / 36
Регистрация: 13.07.2017
Сообщений: 2,270
Записей в блоге: 3
1

Книга "Конечный автомат 2: Возвращение". Часть 1. Разбор. Глава 8. Имя, проверка строки и разбор до. На том ли я пути?

25.12.2018, 18:47. Показов 790. Ответов 15
Метки нет (Все метки)

Наверное, иногда прилюдно выругаться полезно... Стоило мне в предыдущей теме написать "омерзительный конечный автомат", как работа над ним пошла круто вверх. И вот уже есть первый достойный внимания результат.
Полная хронология книги до настоящего момента:
Конечный автомат 2: Возвращение
Часть 1. Разбор
Глава 1. Общие положения
Глава 2. Число и слово
Глава 3. Пропуск и пропуск НИИК
Глава 4. Начало разбора
Глава 5. Вынос объявления
Глава 6. Действие
Глава 7. Условие
Глава 8. Имя, проверка строки и разбор до
...

В этой главе я сделал еще один вынос после главы 5. Там я вынес разбор объявления и зародыш разбора действия из общей функции disassemble(), здесь - разбор имени (состоящего из букв, цифр и пробелов и прерывающегося на зарезервированном слове вида скл) и проверку строки (проверяет следующие символы на соответствие некоторой строке один за другим вне зависимости от их содержания, полезно, например, когда должно быть " : " и ничего другого) из функций разбора объявления и действия, что позволило сократить код по моим оценкам где-то на 8-10%. Также в этой главе появилась функция "разбор до", которая, в отличие от пропуска, не просто сдвигает автомат, а возвращает строку от данной позиции до заданной подстроки включая. Хотелось бы знать, правильно ли я действую и чем еще можно было бы улучшить автомат.

Полный текст главы 8:
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
    class Disassembling {
    public:
        std::vector<Lexem> lexems = std::vector<Lexem>();
        std::string context1 = "", context2 = "", context3 = "";
        std::string string;
        char c;
        size_t pos = 0, string_n = 1, string_start = 0;
        std::string error_message;
 
        Disassembling(std::string new_string) {
            string = new_string;
        }
 
        void get_char() {
            if (pos <= string.length() - 1) {
                c = string[pos];
                pos++;
            }
        }
 
        bool check_char(char tc) {
            if (pos <= string.length() - 1) {
                c = string[pos];
            }
            if (pos <= string.length() - 1 && c == tc) {
                pos++;
                return true;
            }
            else {
                return false;
            }
        }
 
        std::string get_number(char fc) {
            std::string s = (std::string)"" + fc;
            while (pos <= string.length() - 1 && string[pos] >= '0' && string[pos] <= '9') {
                s += string[pos];
                pos++;
            }
            if (pos <= string.length() - 1 && string[pos] == '.') {
                s += string[pos];
                pos++;
                while (pos <= string.length() - 1 && string[pos] >= '0' && string[pos] <= '9') {
                    s += string[pos];
                    pos++;
                }
            }
            if (pos <= string.length() - 1 && (string[pos] == 'E' || string[pos] == 'e')) {
                s += string[pos];
                pos++;
                if (pos <= string.length() - 1 && (string[pos] == '+' || string[pos] == '-')) {
                    s += string[pos];
                    pos++;
                    while (pos <= string.length() - 1 && string[pos] >= '0' && string[pos] <= '9') {
                        s += string[pos];
                        pos++;
                    }
                }
            }
            return s;
        }
 
        std::string get_word(char fc, bool with_spaces = false) {
            std::string s = (std::string)"" + fc;
            while (pos <= string.length() - 1 && ((string[pos] == ' ' && with_spaces == true) || (string[pos] >= '0' && string[pos] <= '9') || (string[pos] >= 'A' && string[pos] <= 'Z') || (string[pos] >= 'a' && string[pos] <= 'z') || (string[pos] >= 'А' && string[pos] <= 'Я') || (string[pos] >= 'а' && string[pos] <= 'я'))) {
                s += string[pos];
                pos++;
            }
            return s;
        }
 
        void skip_until(std::string ts) {
            size_t t = string.find(ts, pos);
            if (t == string.npos) {
                pos = string.length();
            }
            else {
                pos = t + ts.length();
            }
        }
 
        void skip_until_niic(std::string ts) {
            std::string a;
            size_t find_start = pos, t;
        user_operation0:
            t = string.find(ts, find_start);
            if (t == string.npos) {
                pos = string.length();
                return;
            }
            a = string.substr(pos, t - pos);
            if (Database::string_count_niic(a, "\"") % 2 == 1 || Database::string_count_niic(a, "'") % 2 == 1 || Database::string_count_niic(a, "(") > Database::string_count_niic(a, ")") || Database::string_count_niic(a, "[") - Database::string_count_niic(a, " ПРИН [") > Database::string_count_niic(a, "]") || Database::string_count_niic(a, "{") > Database::string_count_niic(a, "}") + 1 || Database::string_count_niic(a, "c::") > Database::string_count_niic(a, "\ng::Конец условия") + 1 || Database::string_count_niic(a, "y::") > Database::string_count_niic(a, "\ng::Конец цикла")) {
                find_start = t + 1;
                goto user_operation0;
            }
            pos = t + ts.length();
        }
 
        std::vector<Lexem> disassemble() {
            while (pos <= string.length() - 1) {
                std::string prefix = "";
                for (int j = 0; j <= 2; j++) {
                    get_char();
                    prefix += c;
                }
                if (prefix != "v::" && prefix != "d::" && prefix != "a::" && prefix != "^::" && prefix != "c::" && prefix != "y::" && prefix != "g::" && prefix != "o::" && prefix != "k::" && prefix != "s::" && prefix != "q::") {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 3 - string_start) + ": некорректный префикс\n";
                    skip_until_niic("\n");
                    string_n++;
                    string_start = pos;
                    continue;
                }
                lexems.push_back(prefix, Lexem::prefix, string_n, pos - 3 - string_start);
                if (prefix == "v::" || prefix == "d::") {
                    disassemble_vd((prefix == "d::"));
                }
                else if (prefix == "a::") {
                    disassemble_a();
                }
                else if (prefix == "c::") {
                    disassemble_c();
                }
                else if (prefix == "y::") {
                    disassemble_y();
                }
            }
        }
 
        void disassemble_vd(bool d = false) {
            get_char();
            if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 'А' && c <= 'Я') || (c >= 'а' && c <= 'я'))) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": имя должно начинаться с буквы\n";
                skip_until_niic("\n");
                string_n++;
                string_start = pos;
                return;
            }
            std::string s = disassemble_name();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                return;
            }
            get_char();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                return;
            }
            if (c == '(') {
                if (s != "Массив") {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": нераспознанный символ \"" + c + "\"\n";
                    skip_until_niic("\n");
                    string_n++;
                    string_start = pos;
                    return;
                }
                else if (d == true) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - s.length() - string_start) + ": использование массива DLL-величин не допускается\n";
                    skip_until_niic("\n");
                    string_n++;
                    string_start = pos;
                    return;
                }
                else {
                    lexems.push_back("(", Lexem::other, string_n, pos - 1 - string_start);
                    disassemble_oal(") ");
                    lexems.push_back(")", Lexem::other, string_n, pos - 2 - string_start);
                    array_passed = true;
                    s = "";
                    if (pos > string.length() - 1) {
                        error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                        a = true;
                        return;
                    }
                    get_char();
                    if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 'А' && c <= 'Я') || (c >= 'а' && c <= 'я'))) {
                        error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": имя должно начинаться с буквы\n";
                        skip_until_niic("\n");
                        string_n++;
                        string_start = pos;
                        return;
                    }
                }
            }
            disassemble_name();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                return;
            }
            if (check_string(" :", false) == false) {
                skip_until_niic("\n");
                string_n++;
                string_start = pos;
                return;
            }
            disassemble_name();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                return;
            }
            if (check_string(" =", false) == false) {
                if (c != '\n') {
                    skip_until_niic("\n");
                    string_n++;
                    string_start = pos;
                }
                return;
            }
            disassemble_expression("\n");
            return;
        }
 
        void disassemble_a() {
            get_char();
            if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 'А' && c <= 'Я') || (c >= 'а' && c <= 'я'))) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": имя должно начинаться с буквы\n";
                skip_until_niic("\n");
                string_n++;
                string_start = pos;
                return;
            }
            disassemble_name();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                return;
            }
            get_char();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                return;
            }
            if (c == '(') {
                lexems.push_back("(", Lexem::other, string_n, pos - 1 - string_start);
                disassemble_oal(")");
                lexems.push_back(")", Lexem::other, string_n, pos - 2 - string_start);
                return;
            }
            else if (c == '+' || c == '-') {
                char c2 = c;
                if (check_char(c2) == false) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": ожидалось \" = \" или \" += \" или \" -= \" или \" *= \" или \" /= \" или \" скл= \" или \" пс= \" или \" спп= \" или \"++\" или \"--\"\n";
                    skip_until_niic("\n");
                    string_n++;
                    string_start = pos;
                    return;
                }
                if (pos > string.length() - 1) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                    return;
                }
                get_char();
                lexems.push_back((std::string)"" + c2 + c2, Lexem::operator_, string_n, pos - 3 - string_start);
                skip_until_niic("\n");
                string_n++;
                string_start = pos;
                return;
            }
            else if (c == ' ') {
                std::string s = disassemble_until_niic(" ");
                if (pos > string.length() - 1) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                    return;
                }
                if (s == "= " || s == "+= " || s == "-= " || s == "*= " || s == "/= " || s == "скл= " || s == "спп= " || s == "пс= ") {
                    lexems.push_back(" " + s, Lexem::operator_, string_n, pos - 2 - string_start);
                    disassemble_expression("\n");
                    return;
                }
                else {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 2 - string_start) + ": ожидалось \" = \" или \" += \" или \" -= \" или \" *= \" или \" /= \" или \" скл= \" или \" пс= \" или \" спп= \" или \"++\" или \"--\"\n";
                    skip_until_niic("\n");
                    string_n++;
                    string_start = pos;
                    return;
                }
            }
            else if (c == '=') {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - last_word.length() - string_start) + ": некорректный оператор присваивания; возможно, вы имели в виду \" скл= \" или \" спп= \" или \" пс= \"?\n";
                skip_until_niic("\n");
                string_n++;
                string_start = pos;
                return;
            }
            else if (c == '\n') {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": неожиданный конец строки; ожидалось \" = \" или \" += \" или \" -= \" или \" *= \" или \" /= \" или \" скл= \" или \" пс= \" или \" спп= \" или \"++\" или \"--\"\n";
                string_n++;
                string_start = pos;
                return;
            }
            else {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": нераспознанный символ \"" + c + "\"\n";
                skip_until_niic("\n");
                string_n++;
                string_start = pos;
                return;
            }
        }
 
        void disassemble_c() {
            get_char();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                a = true;
                return;
            }
            std::string s = get_word(c);
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                a = true;
                return;
            }
            if (s != "УСЛОВИЕ") {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": условие должно начинаться ключевым словом \"УСЛОВИЕ\"\n";
                skip_until_niic("\n");
                string_n++;
                string_start = pos;
                a = true;
                return;
            }
            get_char();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                a = true;
                return;
            }
            if (c != ' ') {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": ожидался пробел\n";
                skip_until_niic("\n");
                string_n++;
                string_start = pos;
                a = true;
                return;
            }
            lexems.push_back(s, Lexem::identifier, string_n, pos - 2 - s.length() - string_start);
            disassemble_c_expression("\n");
            a = true;
            return;
        }
 
        std::string disassemble_name() {
            std::string s = "", last_word = "";
            while (1 == 1) {
                s += ((s != "") ? " " : "") + last_word;
                last_word = get_word(c);
                if (last_word == "XOR" || last_word == "ИЛИ" || last_word == "И" || last_word == "мир" || last_word == "бир" || last_word == "мч" || last_word == "бч" || last_word == "нр" || last_word == "скл" || last_word == "пс" || last_word == "рн" || last_word == "встп" || last_word == "xor" || last_word == "или" || last_word == "и") {
                    pos -= last_word.length() + 1;
                    lexems.push_back(s, Lexem::identifier, string_n, pos - 1 - s.length() - string_start);
                    return s;
                }
                if (pos > string.length() - 1) {
                    return s + " " + last_word;
                }
                get_char();
                if (pos > string.length() - 1) {
                    return s + " " + last_word;
                }
                if (c == ' ') {
                    get_char();
                    if (pos > string.length() - 1) {
                        return s + " " + last_word;
                    }
                    if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 'А' && c <= 'Я') || (c >= 'а' && c <= 'я'))) {
                        pos -= 2;
                        lexems.push_back(s + " " + last_word, Lexem::identifier, string_n, pos - 1 - s.length() - string_start);
                        return s + " " + last_word;
                    }
                }
                else {
                    pos--;
                    return s + " " + last_word;
                }
            }
        }
 
        bool check_string(std::string string, bool accept_end = true, bool space_after = true, bool name_after = true) {
            size_t preserved_pos = pos;
            get_char();
            if (pos > string.length() - 1) {
                if (accept_end == false) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                }
                pos = preserved_pos;
                return false;
            }
            for (int i = 0; i <= string.length() - 1; i++) {
                get_char();
                if (pos > string.length() - 1) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                    pos = preserved_pos;
                    return false;
                }
                if (c == '\n') {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": неожиданный конец строки; ожидалось \" " + string + " \"\n";
                    pos = preserved_pos;
                    return false;
                }
                else if (c != string[i]) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": нераспознанный символ \"" + c + "\"\n";
                    pos = preserved_pos;
                    return false;
                }
            }
            get_char();
            if (pos > string.length() - 1) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                pos = preserved_pos;
                return false;
            }
            if (space_after == true) {
                if (c != ' ') {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": ожидался пробел\n";
                    pos = preserved_pos;
                    return false;
                }
                if (pos > string.length() - 1) {
                    if (accept_end == false) {
                        error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                        pos = preserved_pos;
                        return false;
                    }
                    else {
                        lexems.push_back(" " + string + " ", Lexem::operator_, string_n, pos - 2 - string_start);
                        return true;
                    }
                }
            }
            if (name_after == true) {
                get_char();
                if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 'А' && c <= 'Я') || (c >= 'а' && c <= 'я'))) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": имя должно начинаться с буквы\n";
                    pos = preserved_pos;
                    return false;
                }
                else {
                    lexems.push_back(" " + string + " ", Lexem::operator_, string_n, pos - 2 - string_start);
                    return true;
                }
            }
            lexems.push_back(" " + string + " ", Lexem::operator_, string_n, pos - 2 - string_start);
            return true;
        }
 
        std::string disassemble_until_niic(std::string ts) {
            std::string a;
            size_t find_start = pos, t, t2, pos2 = pos;
        user_operation0:
            t = string.find(ts, find_start);
            t2 = string.find("\n", find_start);
            if (t == string.npos) {
                if (t2 == string.npos) {
                    pos = string.length();
                    return string.substr(pos2, pos - pos2);
                }
                else {
                    t = t2 - ((std::string)"\n").length();
                }
            }
            a = string.substr(pos2, t - pos2);
            if (Database::string_count_niic(a, "\"") % 2 == 1 || Database::string_count_niic(a, "'") % 2 == 1 || Database::string_count_niic(a, "(") > Database::string_count_niic(a, ")") || Database::string_count_niic(a, "[") - Database::string_count_niic(a, " ПРИН [") > Database::string_count_niic(a, "]") || Database::string_count_niic(a, "{") > Database::string_count_niic(a, "}") + 1 || Database::string_count_niic(a, "c::") > Database::string_count_niic(a, "\ng::Конец условия") + 1 || Database::string_count_niic(a, "y::") > Database::string_count_niic(a, "\ng::Конец цикла")) {
                find_start = t + 1;
                goto user_operation0;
            }
            pos = t + ts.length();
            return string.substr(pos2, pos - pos2);
        }
    };
А также некоторые вопросы по DCASTF:
1. Как вы думаете, начиная с какой версии DCASTF можно будет оторваться от C++ и свободно парить на просторах компилятора языка, написанного на этом же языке?
2. Блокам место уже в первой редакции DCASTF, а не в DCASTF+?
3. Величины должны будут быть видны только там, где объявлены? При выходе из этой области автоматически удаляться? Иначе никак? А то у меня есть идея объявлять глобальные величины, используя при этом ключевое слово Глб, а удалять ключевым словом Удалить. (Величины, объявленные без слова Глб, удаляются автоматически.) Кажется интересным, но не возведет ли это мой язык в ранг низкоуровневого?
4. Есть ли какой-то способ разрешить конфликт между количеством доступных для обработки DLL-функций типов и количеством параметров в этих функциях?
5. Возможно, у вас есть еще какие-то предложения к DCASTF? Семафоры какие-нибудь или еще что-то подобное? Только приложите к такому предложению развернутое определение и когда без этого никак или очень тяжело.
Usaga, Rius, Соколиный глаз, прошу вас, не молчите!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.12.2018, 18:47
Ответы с готовыми решениями:

Книга Head First Java, глава 15, задание "Магнитики с кодом"
Здравствуйте. Возникла небольшая проблема с решением этой задачи. Во время решения этой задачи...

Выдаёт ошибку "не удалось создать имя ресурса манифеста ... не удалось найти часть пути"
Сделал проект по c# ,закрыл сохранил,перекинул все папки на флешку,попробовал запустить с файлов...

Реализация абстрактного типа данных "Конечный автомат" (Standard ML)
Мучаюсь я с языком STANDARD ML :( . Мне было дано такое задание: Реализовать тип данных &quot;Конечный...

Завершение потока (разбор кода "Циклы в отдельном потоке")
В предыдущей теме https://www.cyberforum.ru/qt/thread820593.html в общем выяснилось как работает...

15
Эксперт .NET
9326 / 6689 / 1081
Регистрация: 21.01.2016
Сообщений: 25,207
26.12.2018, 06:54 2
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
1. Как вы думаете, начиная с какой версии DCASTF можно будет оторваться от C++ и свободно парить на просторах компилятора языка, написанного на этом же языке?
Вы, для начала, на С++ нормально напишите.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
2. Блокам место уже в первой редакции DCASTF, а не в DCASTF+?
Хз о чём речь, о каких блоках. DCASTF+ - платная редакция? Тот же мусор, но за деньги?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
3. Величины должны будут быть видны только там, где объявлены? При выходе из этой области автоматически удаляться? Иначе никак? А то у меня есть идея объявлять глобальные величины, используя при этом ключевое слово Глб, а удалять ключевым словом Удалить. (Величины, объявленные без слова Глб, удаляются автоматически.) Кажется интересным, но не возведет ли это мой язык в ранг низкоуровневого?
Глобальные переменные - плохо. У переменных должен быть ограниченный скоуп - область видимости.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
4. Есть ли какой-то способ разрешить конфликт между количеством доступных для обработки DLL-функций типов и количеством параметров в этих функциях?
Как этот конфликт разруливается в других языках?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
5. Возможно, у вас есть еще какие-то предложения к DCASTF?
Да, не пишите его. Вы не готовы для этого.

По поводу кода: он ужасен. Всё то, на что вам указывали, здесь по прежнему есть и никуда не делось. Копирование строк заместо передачи по ссылке, конкатенации строк, сабстринги, копипаста везде и всюду, magic numbers\strings, полное отсутствие представления об итераторах, безобразные именования идентификаторов (переменных и методов), GOTO, парсер и лексер в одной куче. Прогресс нулевой.
0
Его Правительские Звания
134 / 115 / 36
Регистрация: 13.07.2017
Сообщений: 2,270
Записей в блоге: 3
26.12.2018, 10:01  [ТС] 3
Цитата Сообщение от Usaga Посмотреть сообщение
Глобальные переменные - плохо.
Учел ваше мнение. Подумаю, чем их заменить.
Цитата Сообщение от Usaga Посмотреть сообщение
Как этот конфликт разруливается в других языках?
Понятия не имею. У вас, мне кажется, больше опыта в этом вопросе.
Цитата Сообщение от Usaga Посмотреть сообщение
Копирование строк заместо передачи по ссылке
Да, это моя вечная проблема. Пойду исправлю.
Цитата Сообщение от Usaga Посмотреть сообщение
конкатенации строк, сабстринги
А как же без этого?
Цитата Сообщение от Usaga Посмотреть сообщение
копипаста везде и всюду
Именно для избавления от копипасты я и сделал второй вынос. Вероятно, нужен еще третий.
Цитата Сообщение от Usaga Посмотреть сообщение
magic numbers\strings
Это что такое?
Цитата Сообщение от Usaga Посмотреть сообщение
полное отсутствие представления об итераторах
Где можно почитать про них? В Википедии есть статья?
Цитата Сообщение от Usaga Посмотреть сообщение
безобразные именования идентификаторов (переменных и методов)
У важных идентификаторов, мне кажется, нормальные имена. У временных и имена временные.
Цитата Сообщение от Usaga Посмотреть сообщение
GOTO
Я читал в какой-то чужой теме, что это устаревший оператор, но по моему личному мнению, в нем нет ничего плохого.
Цитата Сообщение от Usaga Посмотреть сообщение
парсер и лексер в одной куче
Где вы тут увидели построение дерева? Или пишете наперед? Это неправда.
0
Эксперт .NET
9326 / 6689 / 1081
Регистрация: 21.01.2016
Сообщений: 25,207
26.12.2018, 11:17 4
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Учел ваше мнение. Подумаю, чем их заменить.
Может лучше посмотреть как это обходится в других языках, а не придумывать велосипеды?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Понятия не имею. У вас, мне кажется, больше опыта в этом вопросе.
Это вы у нас пишете лучший в мире язык. Вы такие вещи уже должны знать, так ведь?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
А как же без этого?
Буфер, который наполняется в цикле, а по выходу из цикла из него создавать строку? Или раз += написать просто, то можно и говнокодить?)

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Именно для избавления от копипасты я и сделал второй вынос. Вероятно, нужен еще третий.
Я хбз о каком выносе идёт речь. У вас в продемонстрированном коде кругом повторяющиеся условия и блоки кода. Неужели это без постороннего указания вообще не заметно?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Где можно почитать про них? В Википедии есть статья?
Вам про гугл рассказать? Сам в поиск вбить не можете?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
У важных идентификаторов, мне кажется, нормальные имена. У временных и имена временные.
Все - важные. Все должны называться нормально.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Я читал в какой-то чужой теме, что это устаревший оператор, но по моему личному мнению, в нем нет ничего плохого.
Он нарушает структуру кода. Этот оператор можно использовать только в очень редких случаях каких-то оптимизаций и при полном понимании того, что делаете.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Где вы тут увидели построение дерева? Или пишете наперед? Это неправда.
Никаким деревом тут и не пахнет. Но тут идёт не только выборка лексем из входной строки, но и попытки какого-то синтаксического анализа. Сначала нужно построить дерево разбора, а потом уже пытаться его в АСТ перевести со всеми анализами синтаксиса и прочего. А тут всё в кучу. И строки разгребаются, и суффиксы какие-то проверяются, и какие-то фрагменты текста в строке пропускаются... Каша, одним словом.
0
Его Правительские Звания
134 / 115 / 36
Регистрация: 13.07.2017
Сообщений: 2,270
Записей в блоге: 3
26.12.2018, 16:31  [ТС] 5
Цитата Сообщение от Usaga Посмотреть сообщение
Может лучше посмотреть как это обходится в других языках, а не придумывать велосипеды?
Во многих языках есть глобальные переменные.
Цитата Сообщение от Usaga Посмотреть сообщение
Буфер, который наполняется в цикле, а по выходу из цикла из него создавать строку?
Это громоздко.
Цитата Сообщение от Usaga Посмотреть сообщение
Я хбз
Новый термин компьютерного сленга? Возможно, вы имели в виду "хз"?
Цитата Сообщение от Usaga Посмотреть сообщение
Неужели это без постороннего указания вообще не заметно?
Не "вообще", но чтобы заметить, надо потрудиться.
Цитата Сообщение от Usaga Посмотреть сообщение
Вам про гугл рассказать? Сам в поиск вбить не можете?
Прочитал, но как это применимо к моему коду - не понял.
Цитата Сообщение от Usaga Посмотреть сообщение
Но тут идёт не только выборка лексем из входной строки, но и попытки какого-то синтаксического анализа.
Цитата Сообщение от Usaga Посмотреть сообщение
и суффиксы какие-то проверяются
Дело в том, что при разных префиксах (а не суффиксах) абсолютно разный список лексем. Назначение автомата - не просто считывать символ за символом, не видя ничего вокруг, а с каждым символом переходить из одного состояния в другое. А в разных состояниях по-разному считывать. Вот и получается иллюзия "какого-то синтаксического анализа".

Прошу прокомментировать еще одно мое озарение.
Экспрессии - конструкция, которая быстро пишется и быстро выполняется! Бывают трех видов - экспресс-действия, экспресс-условия и экспресс-операции. Например, можно написать:
Код
Экспресс-действие Провал{
	q::Фигурные скобки написаны для ясности, на самом деле их нет.
	Сообщение("Провал!", кТолькоОк, "Игра")
	Очки = 0
	Окно игры.Скрыть()
	Окно выбора уровня.Показать()
	Вернуть Пустота}
Если в любом месте в пределах области объявления экспрессии написать ">::Провал", все эти действия выполнятся, а пустоту вернет не экспресс-действие (оно неспособно возвращать значение), а операция, в которой оно находится. Экспресс-условие пишется так:
Код
Экспресс-условие Буква (Смвкд(Вкс(С, И)) бир Смвкд("A") И Смвкд(Вкс(С, И)) мир Смвкд("Z")) ИЛИ (Смвкд(Вкс(С, И)) бир Смвкд("a") И Смвкд(Вкс(С, И)) мир Смвкд("z")) ИЛИ (Смвкд(Вкс(С, И)) бир Смвкд("А") И Смвкд(Вкс(С, И)) мир Смвкд("Я")) ИЛИ (Смвкд(Вкс(С, И)) бир Смвкд("а") И Смвкд(Вкс(С, И)) мир Смвкд("я"))
Теперь можно написать:
Код
УСЛОВИЕ Вкс(С, И)=" " ИЛИ Буква
При экспресс-условии не нужно и даже нельзя ставить оператор сравнения. А вот экспресс-операция:
Код
Экспресс-операция ЛогКонст : Снн(Строка : Строка, Строка : Подстрока) Перек(1-Модуль(Пвт(Строка, Подстрока)-1), Десв, Ложь)
Экспресс-операция должна быть записана в одну строку. Она может возвращать значение любого типа. Слово "Вернуть" не пишется. Она не может выполнить много действий, а только вернуть одно значение. Она не лучше и не хуже, чем экспресс-условие: если нужно проверить, чтобы где-то была не-буква, экспресс-условие на букву не годится, так как написать "Буква=Ложь" нельзя, и придется писать еще одно экспресс-условие, а в терминах экспресс-операций можно написать "Буква()=Десв" и "Буква()=Ложь". И наоборот, если обратное условие не нужно, экспресс-условие короче, и написать его удобнее, так как экспресс-операцию придется писать через Перек() или аналогичные методы.
Важно: экспрессии не только быстро пишутся (кроме первого раза), но и быстро выполняются. Это достигается благодаря тому, что они не вызываются как операции (надо обработать выражение, затем параметры, затем имя операции, затем ее текст, затем части текста и т. д.), а заменяются своим текстом на этапе парсинга. В экспрессиях разрешено использовать имена локальных величин, объявленных в операции, в которой экспрессия вызывается. Рекурсия экспрессий запрещена. Экспрессия должна быть определена выше, чем использована, поэтому косвенная рекурсия экспрессий также невозможна. Также запрещены вложенные экспрессии.

Особняком стоят экспресс-блоки. Они выполняются, как обычные блоки, но пишутся быстрее, причем именно в первый раз. Например:
Код
Экспресс-блок(Число : Йов, Число : Питч, Число : Ролл) : Операция Получить вращение(ОбъемныйОбъект : Объект)
q::Никаких объемных объектов в DCASTF НЕ БУДЕТ, эта строка - ровным счетом ничего, кроме демонстрации экспресс-блоков.
Экспресс-блок(Строка : Название, ЛогКонст : Холодное, Число : Снятие1, Число : Снятие2, Тип снятия : Тип снятия) : Оружие
Все мы знаем, что операция может вернуть одно значение, а создавать полноценный блок в вышеупомянутых случаях было бы сложно. Экспресс-блок решает эту проблему: он создает блок меньше, чем в одну строку. Этот блок является подчиненным Базблока и содержит конструктор по всем полям и операторы = и нр (aka <>, !=). Экспресс-блок является безымянным, поэтому чтобы объявить одним блоком две конструкции, нужно два раза указывать все его параметры, и поэтому же невозможна рекурсия экспресс-блоков. Значение, присваеваемое экспресс-блоку, записывается так же, как массив.
Ну что, есть в этом смысл? Если нет, можете объяснить, почему? И вы так ничего и не написали по поводу парных кавычек.

А еще попрошу ответить без виляния - вы украинец или нет? А то слова "лютый", "абы как" и подобные намекают на это. Реально, это не для того, чтобы обидеть вас. Чтобы вам было легче признаться, отвечу про себя: я - наполовину украинец и живу в Украине!
0
Эксперт .NET
9326 / 6689 / 1081
Регистрация: 21.01.2016
Сообщений: 25,207
26.12.2018, 18:15 6
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Во многих языках есть глобальные переменные.
В C# и Java нет. Да и наличие возможности не значит, что оно использование её поощряется.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Это громоздко.
И поэтому надо писать неэффективно?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Новый термин компьютерного сленга? Возможно, вы имели в виду "хз"?
Хрен Бы Знал.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Прочитал, но как это применимо к моему коду - не понял.
Значит так прочитали. Последовательно получать символы из исходной строки будет поаккуратнее смотреться и надёжнее, чем вручную индекс вести.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Дело в том, что при разных префиксах (а не суффиксах) абсолютно разный список лексем.
Эти префиксы выглядят как костылина вызванная неумением разобрать код, а не фича языка.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Ну что, есть в этом смысл? Если нет, можете объяснить, почему?
Я не совсем понял, что тут имеется в виду. Expression body method как в C#? Анонимные классы?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
И вы так ничего и не написали по поводу парных кавычек.
А вы спрашивали?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
А еще попрошу ответить без виляния - вы украинец или нет? А то слова "лютый", "абы как" и подобные намекают на это. Реально, это не для того, чтобы обидеть вас. Чтобы вам было легче признаться, отвечу про себя: я - наполовину украинец и живу в Украине!
Я не украинец. В России такие обороты весьма популярны и никак не намекают на украинские корни.
0
Его Правительские Звания
134 / 115 / 36
Регистрация: 13.07.2017
Сообщений: 2,270
Записей в блоге: 3
26.12.2018, 19:33  [ТС] 7
Цитата Сообщение от Usaga Посмотреть сообщение
Последовательно получать символы из исходной строки будет поаккуратнее смотреться и надёжнее, чем вручную индекс вести.
Спасибо за подсказку))) Вы мне прямо Америку открыли с этими итераторами))) Пойду переписывать))) Я не шучу.
Цитата Сообщение от Usaga Посмотреть сообщение
Эти префиксы выглядят как костылина вызванная неумением разобрать код, а не фича языка.
В полной версии вместо префиксов будут картинки. Префиксы уйдут в недра программы.
Цитата Сообщение от Usaga Посмотреть сообщение
Expression body method как в C#? Анонимные классы?
Первое - снова открытие для меня, хоть и не такое великое, как итераторы. По синтаксису похоже. Но я не знаю, на каком этапе эта конструкция раскрывается в C#. У меня - еще на этапе компиляции, причем не вычисляется, а именно раскрывается, заменяясь на свой текст. Думаю, что до такого мало кто может додуматься. Второе тоже похоже.
Цитата Сообщение от Usaga Посмотреть сообщение
А вы спрашивали?
Спрашивал. Там в самом конце сообщения.

Еще хотелось бы спросить - я сильно гружу вас? Или вам доставляет удовольствие болтать?
0
Эксперт .NET
9326 / 6689 / 1081
Регистрация: 21.01.2016
Сообщений: 25,207
27.12.2018, 06:52 8
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Но я не знаю, на каком этапе эта конструкция раскрывается в C#.
Это обычные методы. Просто сокращённый синтаксис.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
У меня - еще на этапе компиляции, причем не вычисляется, а именно раскрывается, заменяясь на свой текст.
В С++ это уже давно есть и называется "макрос".

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Спрашивал. Там в самом конце сообщения.
Да, точно. Такое тоже есть во многих языках. Кавычки внутри строки можно экранировать разными способами. Зависит от языка. В C# делается так:

C#
1
2
var someString  = "this is a\"string\"";
var otherString = @"this is a""string""";
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Еще хотелось бы спросить - я сильно гружу вас? Или вам доставляет удовольствие болтать?
Не грузите.
0
Его Правительские Звания
134 / 115 / 36
Регистрация: 13.07.2017
Сообщений: 2,270
Записей в блоге: 3
27.12.2018, 13:27  [ТС] 9
Цитата Сообщение от Usaga Посмотреть сообщение
Не грузите.
Спасибо. У меня теперь Интернет каждый день, так что можем болтать, сколько захотим. Тем более, это не просто "из пустого в пустое"©, я реально учусь хорошему стилю программирования. Вчера, например, первый раз в жизни узнал об итераторах.
Цитата Сообщение от Usaga Посмотреть сообщение
Да, точно. Такое тоже есть во многих языках. Кавычки внутри строки можно экранировать разными способами. Зависит от языка. В C# делается так:
Хорошо, как вы в C# экранируете следующую строку: <a href=«eval(«document.write(«<input type=text text=«Привет, это главная страница «ООО «КП «Иванов и Ко»»».» style=«position:«absolute»»>»)»)»>? Только не пытайтесь отвертеться, что это "фу", "не практикуется" и т. д., а попытайтесь конкретно экранировать.
Вы так и не объяснили, что такое
Цитата Сообщение от Usaga Посмотреть сообщение
magic numbers\strings
Выкладываю исправленные ошибки, какие смог. Сделал передачу по ссылке и итераторы и прошу указать, где еще есть "копипаста". В тексте присутствуют вопросы, постарайтесь найти и ответить на них.
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
    class Disassembling {
    public:
        std::vector<Lexem> lexems = std::vector<Lexem>();
        std::string context1 = "", context2 = "", context3 = "";
        std::string string;
        std::string::iterator it = string.begin(), begin = string.begin(), string_start = string.begin(), end = string.end();
        char &c = *it;
        size_t string_n = 1;
        std::string error_message;
 
        Disassembling(const std::string &new_string) {
            string = new_string;
        }
 
        void get_char() {
            if (it != end) {
                it++;
            }
        }
 
        bool check_char(char tc) {
            if (it != end && c == tc) {
                it++;
                return true;
            }
            else {
                return false;
            }
        }
 
        bool check_digit() {
            if (it != end && c >= '0' && c <= '9') {
                it++;
                return true;
            }
            else {
                return false;
            }
        }
 
        bool check_letter() {
            if (it != end && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 'А' && c <= 'Я') || (c >= 'а' && c <= 'я'))) {
                it++;
                return true;
            }
            else {
                return false;
            }
        }
 
        bool check_ld() {
            //Нельзя написать check_letter() == true || check_digit() == true, так как тогда, если будет сначала буква, а затем цифра, позиция сдвинется на 2 символа. Господин Usaga, не знаете, как это исправить?
            if (it != end && ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 'А' && c <= 'Я') || (c >= 'а' && c <= 'я'))) {
                it++;
                return true;
            }
            else {
                return false;
            }
        }
 
        std::string get_number(char fc) {
            std::string s = fc + get_number2();
            if (it != end && c == '.') {
                s += c;
                it++;
                s += get_number2();
            }
            if (it != end && (c == 'E' || c == 'e')) {
                s += c;
                it++;
                if (it != end && (c == '+' || c == '-')) {
                    s += c;
                    it++;
                    s += get_number2();
                }
            }
            return s;
        }
 
        std::string get_number2() {
            std::string s = "";
            while (it != end && check_digit() == true) {
                s += c;
                it++;
            }
            return s;
        }
 
        std::string get_word(char fc) {
            std::string s = (std::string)"" + fc;
            while (it != end && check_ld() == true) {
                s += c;
                it++;
            }
            return s;
        }
 
        void skip_until(const std::string &ts) {
            size_t t = string.find(ts, pos);
            if (t == string.npos) {
                pos = string.length();
            }
            else {
                pos = t + ts.length();
            }
        }
 
        //Господин Usaga, не подскажете, как прыгнуть к определенному месту строки с помощью итераторов?
        void skip_until_niic(const std::string &ts) {
            std::string a;
            size_t find_start = pos, t;
        user_operation0:
            t = string.find(ts, find_start);
            if (t == string.npos) {
                pos = string.length();
                return;
            }
            a = string.substr(pos, t - pos);
            if (Database::string_count_niic(a, "\"") % 2 == 1 || Database::string_count_niic(a, "'") % 2 == 1 || Database::string_count_niic(a, "(") > Database::string_count_niic(a, ")") || Database::string_count_niic(a, "[") - Database::string_count_niic(a, " ПРИН [") > Database::string_count_niic(a, "]") || Database::string_count_niic(a, "{") > Database::string_count_niic(a, "}") + 1 || Database::string_count_niic(a, "c::") > Database::string_count_niic(a, "\ng::Конец условия") + 1 || Database::string_count_niic(a, "y::") > Database::string_count_niic(a, "\ng::Конец цикла")) {
                find_start = t + 1;
                goto user_operation0;
            }
            pos = t + ts.length();
        }
 
        bool is_end() {
            if (it == end) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                return true;
            }
            return false;
        }
 
        void generate_error(size_t offset, const std::string &text) {
            if (text != "") {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(it - offset - string_start) + ": " + text + "\n";
            }
            skip_until_niic("\n");
            string_n++;
            string_start = it;
        }
 
        std::vector<Lexem> disassemble() {
            while (it != end) {
                std::string prefix = "";
                for (int j = 0; j <= 2; j++) {
                    get_char();
                    prefix += c;
                }
                if (prefix != "v::" && prefix != "d::" && prefix != "a::" && prefix != "^::" && prefix != "c::" && prefix != "y::" && prefix != "g::" && prefix != "o::" && prefix != "k::" && prefix != "s::" && prefix != "q::") {
                    generate_error(3, "некорректный префикс");
                    continue;
                }
                lexems.push_back(prefix, Lexem::prefix, string_n, it - 3 - string_start);
                if (prefix == "v::" || prefix == "d::") {
                    disassemble_vd((prefix == "d::"));
                }
                else if (prefix == "a::") {
                    disassemble_a();
                }
                else if (prefix == "c::") {
                    disassemble_c();
                }
                else if (prefix == "y::") {
                    disassemble_y();
                }
            }
        }
 
        void disassemble_vd(bool d = false) {
            get_char();
            if (check_letter() == false) {
                generate_error(1, "имя должно начинаться с буквы");
                return;
            }
            std::string s = disassemble_name();
            if (is_end() == true) return; //Еще сильнее не смог сократить, может, поможете?
            get_char();
            if (is_end() == true) return;
            if (c == '(') {
                if (s != "Массив") {
                    generate_error(1, "нераспознанный символ \"" + c + "\"");
                    return;
                }
                else if (d == true) {
                    generate_error(1, "использование массива DLL-величин не допускается");
                    return;
                }
                else {
                    lexems.push_back("(", Lexem::other, string_n, it - 1 - string_start);
                    disassemble_oal(") ");
                    lexems.push_back(")", Lexem::other, string_n, it - 2 - string_start);
                    array_passed = true;
                    s = "";
                    if (is_end() == true) return;
                    get_char();
                    if (check_letter() == false) {
                        generate_error(1, "имя должно начинаться с буквы");
                        return;
                    }
                }
            }
            disassemble_name();
            if (is_end() == true) return;
            if (check_string(" :", false) == false) {
                generate_error(1, "");
                return;
            }
            disassemble_name();
            if (is_end() == true) return;
            if (check_string(" =", false) == false) {
                if (c != '\n') {
                    generate_error(1, "");
                }
                return;
            }
            disassemble_expression("\n");
            return;
        }
 
        void disassemble_a() {
            get_char();
            if (check_letter() == false) {
                generate_error(1, "имя должно начинаться с буквы");
                return;
            }
            disassemble_name();
            if (is_end() == true) return;
            get_char();
            if (is_end() == true) return;
            if (c == '(') {
                lexems.push_back("(", Lexem::other, string_n, it - 1 - string_start);
                disassemble_oal(")");
                lexems.push_back(")", Lexem::other, string_n, it - 2 - string_start);
                return;
            }
            else if (c == '+' || c == '-') {
                char c2 = c;
                if (check_char(c2) == false) {
                    generate_error(1, "ожидалось \" = \" или \" += \" или \" -= \" или \" *= \" или \" /= \" или \" скл= \" или \" пс= \" или \" спп= \" или \"++\" или \"--\"");
                    return;
                }
                if (is_end() == true) return;
                get_char();
                lexems.push_back((std::string)"" + c2 + c2, Lexem::operator_, string_n, it - 3 - string_start);
                generate_error(1, ""); //Тут название функции немного не подходит, но я решил не переименовывать
                return;
            }
            else if (c == ' ') {
                std::string s = disassemble_until_niic(" ");
                if (is_end() == true) return;
                if (s == "= " || s == "+= " || s == "-= " || s == "*= " || s == "/= " || s == "скл= " || s == "спп= " || s == "пс= ") {
                    lexems.push_back(" " + s, Lexem::operator_, string_n, it - 2 - string_start);
                    disassemble_expression("\n");
                    return;
                }
                else {
                    generate_error(s.length() + 1, "ожидалось \" = \" или \" += \" или \" -= \" или \" *= \" или \" /= \" или \" скл= \" или \" пс= \" или \" спп= \" или \"++\" или \"--\"");
                    return;
                }
            }
            else if (c == '=') {
                generate_error(s.length() - s.rfind(" ") + 1, "некорректный оператор присваивания; возможно, вы имели в виду \" скл= \" или \" спп= \" или \" пс= \"?");
                return;
            }
            else if (c == '\n') {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": неожиданный конец строки; ожидалось \" = \" или \" += \" или \" -= \" или \" *= \" или \" /= \" или \" скл= \" или \" пс= \" или \" спп= \" или \"++\" или \"--\"\n";
                string_n++;
                string_start = it;
                return;
            }
            else {
                generate_error(1, "нераспознанный символ \"" + c + "\"");
                return;
            }
        }
 
        void disassemble_c() {
            get_char();
            if (is_end() == true) return;
            std::string s = get_word(c);
            if (is_end() == true) return;
            if (s != "УСЛОВИЕ") {
                generate_error(s.length(), "условие должно начинаться ключевым словом \"УСЛОВИЕ\"");
                return;
            }
            get_char();
            if (is_end() == true) return;
            if (c != ' ') {
                generate_error(1, "ожидался пробел");
                return;
            }
            lexems.push_back(s, Lexem::identifier, string_n, it - 2 - s.length() - string_start);
            disassemble_c_expression("\n");
            return;
        }
 
        std::string disassemble_name() {
            std::string s = "", last_word = "";
            while (1 == 1) {
                s += ((s != "") ? " " : "") + last_word;
                last_word = get_word(c);
                if (last_word == "XOR" || last_word == "ИЛИ" || last_word == "И" || last_word == "мир" || last_word == "бир" || last_word == "мч" || last_word == "бч" || last_word == "нр" || last_word == "скл" || last_word == "пс" || last_word == "рн" || last_word == "встп" || last_word == "xor" || last_word == "или" || last_word == "и") {
                    it -= last_word.length() + 1;
                    lexems.push_back(s, Lexem::identifier, string_n, it - 1 - s.length() - string_start);
                    return s;
                }
                if (it == end) {
                    return s + " " + last_word;
                }
                get_char();
                if (it == end) {
                    return s + " " + last_word;
                }
                if (c == ' ') {
                    get_char();
                    if (it == end) {
                        return s + " " + last_word;
                    }
                    if (check_ld() == false) {
                        it -= 2;
                        lexems.push_back(s + " " + last_word, Lexem::identifier, string_n, it - 1 - s.length() - string_start);
                        return s + " " + last_word;
                    }
                }
                else {
                    it--;
                    return s + " " + last_word;
                }
            }
        }
 
        bool check_string(const std::string &string, bool accept_end = true, bool space_after = true, bool name_after = true) {
            size_t preserved_it = it;
            get_char();
            if (it == end) {
                if (accept_end == false) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                }
                it = preserved_it;
                return false;
            }
            for (int i = 0; i <= string.length() - 1; i++) {
                get_char();
                if (it == end) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                    it = preserved_it;
                    return false;
                }
                if (c == '\n') {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": неожиданный конец строки; ожидалось \" " + string + " \"\n";
                    it = preserved_it;
                    return false;
                }
                else if (c != string[i]) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": нераспознанный символ \"" + c + "\"\n";
                    it = preserved_it;
                    return false;
                }
            }
            get_char();
            if (it == end) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                it = preserved_it;
                return false;
            }
            if (space_after == true) {
                if (c != ' ') {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": ожидался пробел\n";
                    it = preserved_it;
                    return false;
                }
                if (it == end) {
                    if (accept_end == false) {
                        error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                        it = preserved_it;
                        return false;
                    }
                    else {
                        lexems.push_back(" " + string + " ", Lexem::operator_, string_n, it - 2 - string_start);
                        return true;
                    }
                }
            }
            if (name_after == true) {
                get_char();
                if (check_letter() == false) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": имя должно начинаться с буквы\n";
                    it = preserved_it;
                    return false;
                }
                else {
                    lexems.push_back(" " + string + " ", Lexem::operator_, string_n, it - 2 - string_start);
                    return true;
                }
            }
            lexems.push_back(" " + string + " ", Lexem::operator_, string_n, it - 2 - string_start);
            return true;
        }
 
        std::string disassemble_until_niic(const std::string &ts) {
            std::string a;
            size_t find_start = pos, t, t2, pos2 = pos;
        user_operation0:
            t = string.find(ts, find_start);
            t2 = string.find("\n", find_start);
            if (t == string.npos) {
                if (t2 == string.npos) {
                    pos = string.length();
                    return string.substr(pos2, pos - pos2);
                }
                else {
                    t = t2 - ((std::string)"\n").length();
                }
            }
            a = string.substr(pos2, t - pos2);
            if (Database::string_count_niic(a, "\"") % 2 == 1 || Database::string_count_niic(a, "'") % 2 == 1 || Database::string_count_niic(a, "(") > Database::string_count_niic(a, ")") || Database::string_count_niic(a, "[") - Database::string_count_niic(a, " ПРИН [") > Database::string_count_niic(a, "]") || Database::string_count_niic(a, "{") > Database::string_count_niic(a, "}") + 1 || Database::string_count_niic(a, "c::") > Database::string_count_niic(a, "\ng::Конец условия") + 1 || Database::string_count_niic(a, "y::") > Database::string_count_niic(a, "\ng::Конец цикла")) {
                find_start = t + 1;
                goto user_operation0;
            }
            pos = t + ts.length();
            return string.substr(pos2, pos - pos2);
        }
    };
Теперь хронология книги имеет такой вид:
Конечный автомат 2: Возвращение
Часть 1. Разбор
Глава 1. Общие положения
Глава 2. Число и слово
Глава 3. Пропуск и пропуск НИИК
Глава 4. Начало разбора
Глава 5. Вынос объявления
Глава 6. Действие
Глава 7. Условие
Глава 8. Имя, проверка строки и разбор до
Глава 9. Итераторы и третий вынос
...
0
Эксперт .NET
9326 / 6689 / 1081
Регистрация: 21.01.2016
Сообщений: 25,207
27.12.2018, 19:41 10
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Хорошо, как вы в C# экранируете следующую строку: <a href=«eval(«document.write(«<input type=text text=«Привет, это главная страница «ООО «КП «Иванов и Ко»»».» style=«position:«absolute»»>»)»)»>? Только не пытайтесь отвертеться, что это "фу", "не практикуется" и т. д., а попытайтесь конкретно экранировать.
Я выше пример привёл. Вполне себе наглядный.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Вы так и не объяснили, что такое
Вы и не спросили. Это строковые литералы и какие-то числа в коде, значение которых сложно понять по месту их использования. Bad practice.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Теперь хронология книги имеет такой вид:
Вы уже книгу пишете?.. А как же DCASTF? А игры? А архиватор? И чем вы с читателями поделиться собрались, когда сами ничего толком не знаете?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Выкладываю исправленные ошибки, какие смог.
Я бы не сказал, что стало сильно лучше) На вскидку:

* Всё содержимое класса объявлено публичным. Это потому, что "гладиолус" или так надо?)
* Методы check_* делают не то, что у них заявлено в именах. Они не только "проверяют" символ, но и перемещают указатель итератора не следующую позицию. Криво и не правильно. И в каждом из таких методов код начинается с одного и того же. Вы не заметили? Это не видно?
* Условия проверки символов повторяются. Это тоже вообще не видно? Есть проверка на соответствие латинице. В какой кодировке? Кто-то сохранит документ в CP1251, кто-то в UTF-8. Что будет с вашим парсером?
* Это что за дичь: std::string s = (std::string)"" + fc;
* Круто, чё: error_message += "Ошибка в строке " +
* Ходим по исходной строке вдоль и поперёк?))) t = string.find(ts, find_start);

Вы книжку-то читали, что я посоветовал? По компиляторам? Я понимаю, что нет. Вы хотите методом говнотыка написать что? Продаваемый крутой продукт?
0
Его Правительские Звания
134 / 115 / 36
Регистрация: 13.07.2017
Сообщений: 2,270
Записей в блоге: 3
27.12.2018, 20:15  [ТС] 11
Цитата Сообщение от Usaga Посмотреть сообщение
Вы и не спросили.
Спросил. И где же такие явления у меня? generate_error(magic_number, ...);?
Цитата Сообщение от Usaga Посмотреть сообщение
Вы уже книгу пишете?.. А как же DCASTF? А игры? А архиватор? И чем вы с читателями поделиться собрались, когда сами ничего толком не знаете?
Книга - это аллегория.
Цитата Сообщение от Usaga Посмотреть сообщение
Всё содержимое класса объявлено публичным. Это потому, что "гладиолус" или так надо?)
Это потому, что я не знаю, как может быть иначе. Желаете просветить?
Цитата Сообщение от Usaga Посмотреть сообщение
Методы check_* делают не то, что у них заявлено в именах. Они не только "проверяют" символ, но и перемещают указатель итератора не следующую позицию. Криво и не правильно.
Мне кажется, все правильно, если проверка успешна, итератор сдвигается, чтобы проверять уже следующий символ. Если ошибка, можно проверять на что-нибудь другое.
Цитата Сообщение от Usaga Посмотреть сообщение
И в каждом из таких методов код начинается с одного и того же. Вы не заметили? Это не видно?
Это с чего же? it != end? Мне кажется, тут все предельно кратко.
Цитата Сообщение от Usaga Посмотреть сообщение
Условия проверки символов повторяются. Это тоже вообще не видно?
Там стоит комментарий, почему нельзя не повторять. С вопросом.
Цитата Сообщение от Usaga Посмотреть сообщение
Кто-то сохранит документ в CP1251, кто-то в UTF-8. Что будет с вашим парсером?
Вероятно, когда-нибудь перепишу в Юникоде.
Цитата Сообщение от Usaga Посмотреть сообщение
Это что за дичь: std::string s = (std::string)"" + fc;
Строка состоит из одного символа, а так как нельзя присваивать строке символ, а также нельзя прибавлять символ к указателю, то приведенный вариант - единственно возможный.
Цитата Сообщение от Usaga Посмотреть сообщение
Круто, чё: error_message += "Ошибка в строке " +
Цитата Сообщение от Usaga Посмотреть сообщение
Ходим по исходной строке вдоль и поперёк?))) t = string.find(ts, find_start);
Этих замечаний я не понял.
Вы вопросы найти в коде не смогли? Их вообще не видно?
Цитата Сообщение от Usaga Посмотреть сообщение
Вы книжку-то читали, что я посоветовал? По компиляторам? Я понимаю, что нет.
Открою Америку теперь уже вам - читал! Хоть и не вчитывался в каждую букву. Но на это ушли бы несколько дней в предельно интенсивном режиме либо годы в легком режиме. Но кое-что я понял. Основное - то, что там используется конструкция extends, аналогов которой в C++ нет - там же, где и про парные кавычки, я писал про подчинение и расширение.
0
Эксперт .NET
9326 / 6689 / 1081
Регистрация: 21.01.2016
Сообщений: 25,207
28.12.2018, 07:11 12
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
И где же такие явления у меня?
Примеры:
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
if (s == "= " || s == "+= " || s == "-= " || s == "*= " || s == "/= " || s == "скл= " || s == "спп= " || s == "пс= ") {
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
if (s != "УСЛОВИЕ") {
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
for (int j = 0; j <= 2; j++) {
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
if (prefix == "v::" || prefix == "d::") {
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
lexems.push_back(prefix, Lexem:refix, string_n, it - 3 - string_start);
И прочее. Весь код этим напичкан.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Это потому, что я не знаю, как может быть иначе. Желаете просветить?
Нет, не желаю. Это основы основ, которые есть в любом учебнике по языку. Это не та вещь, к которой нужно долго идти. Оно действительно разбирается в первых главах любого учебника. И пока вы хотя бы один не прочтёте, вы и не узнаете. Собственно, мы снова возвращаемся к вопросу о том, как можно писать (лучшую) замену языку, которого вообще не знаешь.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Мне кажется, все правильно, если проверка успешна, итератор сдвигается, чтобы проверять уже следующий символ. Если ошибка, можно проверять на что-нибудь другое.
Проверка должна только проверять. Состояние системы она менять не должна. Иначе это уже не проверка никакая. Управление потоком символов должно быть в одном месте, а не размазано по всему коду. Оттуда и неудобства.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Это с чего же? it != end? Мне кажется, тут все предельно кратко.
Оно 100500 раз повторяется. Это копипаста и её много.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Там стоит комментарий, почему нельзя не повторять. С вопросом.
Нельзя потому, что ваши проверки меняют состояние (проматывают итератор). А это в корне не верно. Сами сделали себе говнокод, которым сами же и не можете воспользоваться.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Вероятно, когда-нибудь перепишу в Юникоде.
Не утруждайте себя.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Строка состоит из одного символа, а так как нельзя присваивать строке символ, а также нельзя прибавлять символ к указателю, то приведенный вариант - единственно возможный.
Весь фрагмент кода - дерьмо. Начиная с обсуждаемой строки.

C#
1
2
3
4
5
6
7
8
        std::string get_word(char fc) {
            std::string s = (std::string)"" + fc; // ёкарный бабай
            while (it != end && check_ld() == true) { // check_ld() проверяет неизвестно что.
                s += c; // каждое такое действие ведёт к пересозданию объекта строки.
                it++;    // тоже самое делается и в check_ld().
            }
            return s;
        }
Это уродливый и неэффективный код. Выделите буфер под символы и набивайте его входящими символами. Если буфера не хватит, то создайте больший, пересите в него данные из старого, а старый уничтожьте. Потом из буфера создайте строку. Если нужные символы в исходной строке идут подряд, без пропусков, то можно вообще без всяких буферов обойтись: тупо определить индекс первого символа и индекс последнего, а потом уже сделать substring. Но вот придумывать оправдания такому говнокоду ("по другому и не сделать") не надо. Вам уже мешали языки уровень в игре начать сначала, так что я вам не верю.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Этих замечаний я не понял.
Вы вопросы найти в коде не смогли? Их вообще не видно?
Сообщения об ошибках нужно складывать в коллекцию отдельную. И можно из представлять целыми объектами, а не тупо строкой. Так больше информации можно собрать, а её представление сформировать в момент показа пользователю.
В парсерах не должно быть никаких string::find. Вы по строке идёте строго в одну сторону. У вас автомат или что?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Открою Америку теперь уже вам - читал! Хоть и не вчитывался в каждую букву. Но на это ушли бы несколько дней в предельно интенсивном режиме либо годы в легком режиме. Но кое-что я понял. Основное - то, что там используется конструкция extends, аналогов которой в C++ нет - там же, где и про парные кавычки, я писал про подчинение и расширение.
Значит не читали.
0
Его Правительские Звания
134 / 115 / 36
Регистрация: 13.07.2017
Сообщений: 2,270
Записей в блоге: 3
28.12.2018, 13:32  [ТС] 13
Цитата Сообщение от Usaga Посмотреть сообщение
if (s == "= " || s == "+= " || s == "-= " || s == "*= " || s == "/= " || s == "скл= " || s == "спп= " || s == "пс= ") {
Это - не магические строки, а операторы присваивания.
Цитата Сообщение от Usaga Посмотреть сообщение
if (s != "УСЛОВИЕ") {
Из слова "УСЛОВИЕ" не понятен смысл?
Цитата Сообщение от Usaga Посмотреть сообщение
for (int j = 0; j <= 2; j++) {
Длина префикса - 3.
Цитата Сообщение от Usaga Посмотреть сообщение
if (prefix == "v::" || prefix == "d::") {
Префиксы буквально равны этому.
Цитата Сообщение от Usaga Посмотреть сообщение
lexems.push_back(prefix, Lexem:refix, string_n, it - 3 - string_start);
Здесь вообще не вижу ничего магического. А смайл прикольный.
Цитата Сообщение от Usaga Посмотреть сообщение
Это основы основ, которые есть в любом учебнике по языку.
Сделал переменные приватными.
Цитата Сообщение от Usaga Посмотреть сообщение
Проверка должна только проверять. Состояние системы она менять не должна. Иначе это уже не проверка никакая.
Заменил слово check на validate.
Цитата Сообщение от Usaga Посмотреть сообщение
Оно 100500 раз повторяется. Это копипаста и её много.
it != endкороче, чем is_end() == false. Или вы знаете, как не "копипастить" ни то, ни другое?
Цитата Сообщение от Usaga Посмотреть сообщение
Нельзя потому, что ваши проверки меняют состояние (проматывают итератор). А это в корне не верно. Сами сделали себе говнокод, которым сами же и не можете воспользоваться.
Исправил.
Цитата Сообщение от Usaga Посмотреть сообщение
Весь фрагмент кода - дерьмо. Начиная с обсуждаемой строки.
Исправил.
Цитата Сообщение от Usaga Посмотреть сообщение
Если нужные символы в исходной строке идут подряд, без пропусков, то можно вообще без всяких буферов обойтись: тупо определить индекс первого символа и индекс последнего, а потом уже сделать substring.
Так и сделал.
Цитата Сообщение от Usaga Посмотреть сообщение
В парсерах не должно быть никаких string::find. Вы по строке идёте строго в одну сторону. У вас автомат или что?
Вся соль в функции string_count_niic(), которую я не могу переделать. Вызывать ее на каждом символе очень расточительно, а один раз, скажем, за 25 символов - даст неверный результат.
Цитата Сообщение от Usaga Посмотреть сообщение
Значит не читали.
Не хочу спорить.
...
Глава 10. Дела приватные
...
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
    class Disassembling {
        std::vector<Lexem> lexems = std::vector<Lexem>();
        std::string context1 = "", context2 = "", context3 = "";
        std::string string;
        std::string::iterator it = string.begin(), begin = string.begin(), string_start = string.begin(), end = string.end();
        char &c = *it;
        size_t string_n = 1;
        std::string error_message;
 
    public:
        Disassembling(const std::string &new_string) {
            string = new_string;
        }
 
        void get_char() {
            if (it != end) {
                it++;
            }
        }
 
        bool validate_char(char tc) {
            if (it != end && c == tc) {
                it++;
                return true;
            }
            else {
                return false;
            }
        }
 
        bool check_digit() {
            if (it != end && c >= '0' && c <= '9') {
                return true;
            }
            else {
                return false;
            }
        }
 
        bool check_letter() {
            if (it != end && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= 'А' && c <= 'Я') || (c >= 'а' && c <= 'я'))) {
                return true;
            }
            else {
                return false;
            }
        }
 
        bool check_ld() {
            return check_letter() || check_digit();
        }
 
        std::string get_number(char fc) {
            std::string s = get_number2();
            if (it != end && c == '.') {
                it++;
                s += c + get_number2();
            }
            if (it != end && (c == 'E' || c == 'e')) {
                char c2 = c;
                it++;
                if (it != end && (c == '+' || c == '-')) {
                    it++;
                    s += (std::string)"" + c2 + c + get_number2();
                }
            }
            return s;
        }
 
        std::string get_number2() {
            size_t start = it - begin;
            while (it != end && check_digit() == true) {
                it++;
            }
            return string.substr(start, it - begin - start);
        }
 
        std::string get_word(bool first_letter = true) {
            size_t start = it - begin;
            if ((first_letter ? check_letter() : check_ld()) == true) {
                it++;
            }
            while (it != end && check_ld() == true) {
                it++;
            }
            return string.substr(start, it - begin - start);
        }
 
        //Эта функция, вероятно, будет не нужна, но пока что не факт, так что закомментирую ее
        /*void skip_until(const std::string &ts) {
            size_t t = string.find(ts, pos);
            if (t == string.npos) {
                pos = string.length();
            }
            else {
                pos = t + ts.length();
            }
        }*/
 
        //Эту функцию я пока бессилен заменить
        void skip_until_niic(const std::string &ts) {
            std::string a;
            size_t find_start = pos, t;
        user_operation0:
            t = string.find(ts, find_start);
            if (t == string.npos) {
                pos = string.length();
                return;
            }
            a = string.substr(pos, t - pos);
            if (Database::string_count_niic(a, "\"") % 2 == 1 || Database::string_count_niic(a, "'") % 2 == 1 || Database::string_count_niic(a, "(") > Database::string_count_niic(a, ")") || Database::string_count_niic(a, "[") - Database::string_count_niic(a, " ПРИН [") > Database::string_count_niic(a, "]") || Database::string_count_niic(a, "{") > Database::string_count_niic(a, "}") + 1 || Database::string_count_niic(a, "c::") > Database::string_count_niic(a, "\ng::Конец условия") + 1 || Database::string_count_niic(a, "y::") > Database::string_count_niic(a, "\ng::Конец цикла")) {
                find_start = t + 1;
                goto user_operation0;
            }
            pos = t + ts.length();
        }
 
        bool is_end() {
            if (it == end) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                return true;
            }
            return false;
        }
 
        void generate_error(size_t offset, const std::string &text) {
            if (text != "") {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(it - offset - string_start) + ": " + text + "\n";
            }
            skip_until_niic("\n");
            string_n++;
            string_start = it;
        }
 
        std::vector<Lexem> disassemble() {
            while (it != end) {
                std::string prefix = "";
                for (int j = 0; j <= 2; j++) {
                    get_char();
                    prefix += c;
                }
                if (prefix != "v::" && prefix != "d::" && prefix != "a::" && prefix != "^::" && prefix != "c::" && prefix != "y::" && prefix != "g::" && prefix != "o::" && prefix != "k::" && prefix != "s::" && prefix != "q::") {
                    generate_error(3, "некорректный префикс");
                    continue;
                }
                lexems.push_back(prefix, Lexem::prefix, string_n, it - 3 - string_start);
                if (prefix == "v::" || prefix == "d::") {
                    disassemble_vd((prefix == "d::"));
                }
                else if (prefix == "a::") {
                    disassemble_a();
                }
                else if (prefix == "c::") {
                    disassemble_c();
                }
                else if (prefix == "y::") {
                    disassemble_y();
                }
            }
        }
 
        void disassemble_vd(bool d = false) {
            get_char();
            if (check_letter() == false) {
                generate_error(1, "имя должно начинаться с буквы");
                return;
            }
            std::string s = disassemble_name();
            if (is_end() == true) return;
            get_char();
            if (is_end() == true) return;
            if (c == '(') {
                if (s != "Массив") {
                    generate_error(1, "нераспознанный символ "" + c + """);
                    return;
                }
                else if (d == true) {
                    generate_error(1, "использование массива DLL-величин не допускается");
                    return;
                }
                else {
                    lexems.push_back("(", Lexem::other, string_n, it - 1 - string_start);
                    disassemble_oal(") ");
                    lexems.push_back(")", Lexem::other, string_n, it - 2 - string_start);
                    array_passed = true;
                    s = "";
                    if (is_end() == true) return;
                    get_char();
                    if (check_letter() == false) {
                        generate_error(1, "имя должно начинаться с буквы");
                        return;
                    }
                }
            }
            disassemble_name();
            if (is_end() == true) return;
            if (validate_string(" :", false) == false) {
                generate_error(1, "");
                return;
            }
            disassemble_name();
            if (is_end() == true) return;
            if (validate_string(" =", false) == false) {
                if (c != '\n') {
                    generate_error(1, "");
                }
                return;
            }
            disassemble_expression("\n");
            return;
        }
 
        void disassemble_a() {
            get_char();
            if (check_letter() == false) {
                generate_error(1, "имя должно начинаться с буквы");
                return;
            }
            disassemble_name();
            if (is_end() == true) return;
            get_char();
            if (is_end() == true) return;
            if (c == '(') {
                lexems.push_back("(", Lexem::other, string_n, it - 1 - string_start);
                disassemble_oal(")");
                lexems.push_back(")", Lexem::other, string_n, it - 2 - string_start);
                return;
            }
            else if (c == '+' || c == '-') {
                char c2 = c;
                if (validate_char(c2) == false) {
                    generate_error(1, "ожидалось " = " или " += " или " -= " или " *= " или " /= " или " скл= " или " пс= " или " спп= " или "++" или "--"");
                    return;
                }
                if (is_end() == true) return;
                get_char();
                lexems.push_back((std::string)"" + c2 + c2, Lexem::operator_, string_n, it - 3 - string_start);
                generate_error(1, "");
                return;
            }
            else if (c == ' ') {
                std::string s = disassemble_until_niic(" ");
                if (is_end() == true) return;
                if (s == "= " || s == "+= " || s == "-= " || s == "*= " || s == "/= " || s == "скл= " || s == "спп= " || s == "пс= ") {
                    lexems.push_back(" " + s, Lexem::operator_, string_n, it - 2 - string_start);
                    disassemble_expression("\n");
                    return;
                }
                else {
                    generate_error(s.length() + 1, "ожидалось " = " или " += " или " -= " или " *= " или " /= " или " скл= " или " пс= " или " спп= " или "++" или "--"");
                    return;
                }
            }
            else if (c == '=') {
                generate_error(s.length() - s.rfind(" ") + 1, "некорректный оператор присваивания; возможно, вы имели в виду " скл= " или " спп= " или " пс= "?");
                return;
            }
            else if (c == '\n') {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": неожиданный конец строки; ожидалось " = " или " += " или " -= " или " *= " или " /= " или " скл= " или " пс= " или " спп= " или "++" или "--"\n";
                string_n++;
                string_start = it;
                return;
            }
            else {
                generate_error(1, "нераспознанный символ "" + c + """);
                return;
            }
        }
 
        void disassemble_c() {
            get_char();
            if (is_end() == true) return;
            std::string s = get_word(c);
            if (is_end() == true) return;
            if (s != "УСЛОВИЕ") {
                generate_error(s.length(), "условие должно начинаться ключевым словом "УСЛОВИЕ"");
                return;
            }
            get_char();
            if (is_end() == true) return;
            if (c != ' ') {
                generate_error(1, "ожидался пробел");
                return;
            }
            lexems.push_back(s, Lexem::identifier, string_n, it - 2 - s.length() - string_start);
            disassemble_c_expression("\n");
            return;
        }
 
        std::string disassemble_name() {
            std::string last_word = "";
            int start = it - begin, prev_it;
            while (1 == 1) {
                prev_it = it;
                last_word = get_word((prev_it - begin == start));
                if (last_word = "" || last_word == "XOR" || last_word == "ИЛИ" || last_word == "И" || last_word == "мир" || last_word == "бир" || last_word == "мч" || last_word == "бч" || last_word == "нр" || last_word == "скл" || last_word == "пс" || last_word == "рн" || last_word == "встп" || last_word == "xor" || last_word == "или" || last_word == "и") {
                    it = prev_it;
                    lexems.push_back(string.substr(start, it - begin - start), Lexem::identifier, string_n, it - 1 - s.length() - string_start);
                    return string.substr(start, it - begin - start);
                }
                std::string nstr = string.substr(start, it - begin - start);
                if (it == end) {
                    return nstr;
                }
                get_char();
                if (it == end) {
                    return nstr;
                }
                if (c != ' ') {
                    it--;
                    return nstr;
                }
            }
        }
 
        bool validate_string(const std::string &string, bool accept_end = true, bool space_after = true, bool name_after = true) {
            size_t preserved_it = it;
            get_char();
            if (it == end) {
                if (accept_end == false) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                }
                it = preserved_it;
                return false;
            }
            for (int i = 0; i <= string.length() - 1; i++) {
                get_char();
                if (it == end) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                    it = preserved_it;
                    return false;
                }
                if (c == '\n') {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": неожиданный конец строки; ожидалось " " + string + " "\n";
                    it = preserved_it;
                    return false;
                }
                else if (c != string[i]) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": нераспознанный символ "" + c + ""\n";
                    it = preserved_it;
                    return false;
                }
            }
            get_char();
            if (it == end) {
                error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                it = preserved_it;
                return false;
            }
            if (space_after == true) {
                if (c != ' ') {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": ожидался пробел\n";
                    it = preserved_it;
                    return false;
                }
                if (it == end) {
                    if (accept_end == false) {
                        error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - string_start) + ": неожиданный конец\n";
                        it = preserved_it;
                        return false;
                    }
                    else {
                        lexems.push_back(" " + string + " ", Lexem::operator_, string_n, it - 2 - string_start);
                        return true;
                    }
                }
            }
            if (name_after == true) {
                get_char();
                if (check_letter() == false) {
                    error_message += "Ошибка в строке " + std::to_string(string_n) + " в позиции " + std::to_string(pos - 1 - string_start) + ": имя должно начинаться с буквы\n";
                    it = preserved_it;
                    return false;
                }
                else {
                    lexems.push_back(" " + string + " ", Lexem::operator_, string_n, it - 2 - string_start);
                    return true;
                }
            }
            lexems.push_back(" " + string + " ", Lexem::operator_, string_n, it - 2 - string_start);
            return true;
        }
 
        //Здесь я пока тоже бессилен. Все дело в функции string_count_niic(), которую нечем заменить. Не поможете?
        std::string disassemble_until_niic(const std::string &ts) {
            std::string a;
            size_t find_start = pos, t, t2, pos2 = pos;
        user_operation0:
            t = string.find(ts, find_start);
            t2 = string.find("\n", find_start);
            if (t == string.npos) {
                if (t2 == string.npos) {
                    pos = string.length();
                    return string.substr(pos2, pos - pos2);
                }
                else {
                    t = t2 - ((std::string)"\n").length();
                }
            }
            a = string.substr(pos2, t - pos2);
            if (Database::string_count_niic(a, "\"") % 2 == 1 || Database::string_count_niic(a, "'") % 2 == 1 || Database::string_count_niic(a, "(") > Database::string_count_niic(a, ")") || Database::string_count_niic(a, "[") - Database::string_count_niic(a, " ПРИН [") > Database::string_count_niic(a, "]") || Database::string_count_niic(a, "{") > Database::string_count_niic(a, "}") + 1 || Database::string_count_niic(a, "c::") > Database::string_count_niic(a, "\ng::Конец условия") + 1 || Database::string_count_niic(a, "y::") > Database::string_count_niic(a, "\ng::Конец цикла")) {
                find_start = t + 1;
                goto user_operation0;
            }
            pos = t + ts.length();
            return string.substr(pos2, pos - pos2);
        }
    };
Текст функции string_count_niic(). Реально ли ее переделать?
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
    static long int string_count_niic(std::string str, std::string substr, size_t _Off = 0U) {
        long int t = 0;
        std::string s;
        bool double_ic = false, single_ic = false, lock_double_ic = false, lock_single_ic = false;
        if (str.find(substr, _Off) == str.npos) {
            return 0;
        }
        if (substr.find("\"") != substr.npos) {
            lock_double_ic = true;
        }
        if (substr.find("'") != substr.npos) {
            lock_single_ic = true;
        }
        if (str.find(substr, _Off) < str.find("\"", _Off) || str.find("'", _Off) < str.find("\"", _Off) || str.find("\"", _Off) == str.npos || lock_double_ic == true) {
            if (str.find(substr, _Off) < str.find("'", _Off) || str.find("'", _Off) == str.npos || lock_single_ic == true) {
                s = str.substr(str.find(substr, _Off) + substr.length(), str.length() - str.find(substr, _Off) - substr.length());
                if (substr == "\"") {
                    double_ic = true;
                }
                else if (substr == "'") {
                    single_ic = true;
                }
                t = 1;
            }
            else {
                s = str.substr(str.find("'", _Off) + ((std::string)"'").length(), str.length() - str.find("'", _Off) - ((std::string)"'").length());
                single_ic = true;
            }
        }
        else {
            s = str.substr(str.find("\"", _Off) + ((std::string)"\"").length(), str.length() - str.find("\"", _Off) - ((std::string)"\"").length());
            double_ic = true;
        }
        while (s.find(substr) != s.npos) {
            if (s.find(substr) < s.find("\"") || s.find("'") < s.find("\"") || s.find("\"") == s.npos || lock_double_ic == true) {
                if (s.find(substr) < s.find("'") || s.find("'") == s.npos || lock_single_ic == true) {
                    s = s.substr(s.find(substr) + substr.length(), s.length() - s.find(substr) - substr.length());
                    if (substr == "\"" && single_ic == false) {
                        double_ic = !double_ic;
                        t++;
                    }
                    else if (substr == "'" && double_ic == false) {
                        single_ic = !single_ic;
                        t++;
                    }
                    else if (double_ic == false && single_ic == false) {
                        t++;
                    }
                }
                else {
                    s = s.substr(s.find("'") + ((std::string)"'").length(), s.length() - s.find("'") - ((std::string)"'").length());
                    if (double_ic == false) {
                        single_ic = !single_ic;
                    }
                }
            }
            else {
                s = s.substr(s.find("\"") + ((std::string)"\"").length(), s.length() - s.find("\"") - ((std::string)"\"").length());
                if (single_ic == false) {
                    double_ic = !double_ic;
                }
            }
        }
        return t;
    }
P. S. Всего 13 ответов, а уже самая длинная страница в истории моей переписки (по пиксельной высоте)...
0
Эксперт .NET
9326 / 6689 / 1081
Регистрация: 21.01.2016
Сообщений: 25,207
28.12.2018, 17:38 14
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Это - не магические строки, а операторы присваивания.
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Из слова "УСЛОВИЕ" не понятен смысл?
Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Длина префикса - 3.
Такие вещи принято выносить в константы или ресурсы (если поддерживается языком).

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Заменил слово check на validate.
Валидация - проверка на соответствие требованиям. Она так же не должна изменять состояние.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
it != endкороче, чем is_end() == false. Или вы знаете, как не "копипастить" ни то, ни другое?
Да, знаю. Делать эту проверку перед вызовом метода. И !is_end() ещё короче.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Вся соль в функции string_count_niic(), которую я не могу переделать. Вызывать ее на каждом символе очень расточительно, а один раз, скажем, за 25 символов - даст неверный результат.
И снова язык мешает сделать правильно?

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Текст функции string_count_niic(). Реально ли ее переделать?
Нет. Это подлежит выбрасыванию. Даже знать не хочу, что оно считает и зачем. Столько string::find в одном месте я никогда в жизни не встречал.
0
Его Правительские Звания
134 / 115 / 36
Регистрация: 13.07.2017
Сообщений: 2,270
Записей в блоге: 3
08.01.2019, 17:19  [ТС] 15
...
Глава 11. Битва титанов
...
Одиннадцать дней и одиннадцать ночей бились два титана - титанические усилия в моем лице и титанически сложная работа, которой является написание функции disassemble_until_niic без string::find. Три раза я побывал в нокдауне. На двенадцатый день с небес сошел ангел и подарил мне невероятно редкий артефакт - Сиреневую Звезду, с помощью которой я добил титана за два часа. Таких Звезд во всей Вселенной насчитывается несколько десятков, и одну из них я использовал сегодня. В последние пятнадцать минут я нашел еще несколько string::find и успешно убрал их. Естественно, после такого длительного боя я уже не могу писать другие функции, поэтому они не изменились и выкладывать их нет смысла. Вот текст обновленной функции disassemble_until_niic, может быть, еще вы найдете где-нибудь спрятавшийся string::find?
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
        std::string disassemble_until_niic(const std::string &ts, bool stop_at_string_end = true) {
            int start = it - begin;
            bool double_ic = false, single_ic = false, lock_double_ic = false, lock_single_ic = false, ts_has_ic = false;
            int pair_ic = 0, round_bk = 0, square_bk = 0, figure_bk = 0;
            int conditions = 0, cycles = 0, prin = 0, round_bk_after_prin = 0, square_bk_after_prin = 0;
            constexpr std::string key_string[5] = { " ПРИН [", "c::", "\ng::Конец условия", "y::", "\ng::Конец цикла" };
            std::string::iterator key_string_begin[5] = { key_string[0].begin(), key_string[1].begin(), key_string[2].begin(), key_string[3].begin(), key_string[4].begin() };
            std::string::iterator key_string_it[5] = key_string_begin;
            std::string::iterator key_string_end[5] = { key_string[0].end(), key_string[1].end(), key_string[2].end(), key_string[3].end(), key_string[4].end() };
            std::string::iterator ts_begin = ts.begin(), ts_it = ts_begin, ts_end = ts.end();
            if (ts == "") {
                return "";
            }
            for (; ts_it != ts_end; ts_it++) {
                if (*ts_it == "\"") {
                    lock_double_ic = true;
                    ts_has_ic = true;
                }
                if (*ts_it == "'") {
                    lock_single_ic = true;
                    ts_has_ic = true;
                }
                if (*ts_it == "«" || *ts_it == "»") {
                    ts_has_ic = true;
                }
            }
            ts_it = ts_begin;
            for (; it != end; it++) {
                if (c == *ts_it) {
                    ts_it++;
                    if (ts_it == ts_end && double_ic == false && single_ic == false && pair_ic == 0 && round_bk == 0 && square_bk == 0 && figure_bk == 0 && conditions == 0 && cycles == 0 && prin == 0) {
                        return string.substr(start, it - begin - start);
                    }
                }
                else {
                    ts_it = ts_begin;
                }
                if (c == '\n' && stop_at_string_end == true) {
                    return string.substr(start, it - begin - start);
                }
                if (c == "\"" && single_ic == false && pair_ic == 0 && lock_double_ic == false) {
                    double_ic = !double_ic;
                }
                if (c == "'" && double_ic == false && pair_ic == 0 && lock_single_ic == false) {
                    single_ic = !single_ic;
                }
                if (c == "«" && double_ic == false && single_ic == false) {
                    pair_ic++;
                }
                if (c == "»" && double_ic == false && single_ic == false && pair_ic > 0) {
                    pair_ic--;
                    if (pair_ic < 0) {
                        pair_ic = 0;
                    }
                }
                if (c == '(' && double_ic == false && single_ic == false && pair_ic == 0 && ts_has_ic == false) {
                    if (prin == 1) {
                        round_bk_after_prin++;
                    }
                    else {
                        round_bk++;
                    }
                }
                if (c == ')' && double_ic == false && single_ic == false && pair_ic == 0 && ts_has_ic == false && round_bk > 0) {
                    if (prin == 1) {
                        if (round_bk_after_prin == 0) {
                            prin--;
                            if (prin < 0) {
                                prin = 0;
                            }
                        }
                        else {
                            round_bk_after_prin--;
                            if (round_bk_after_prin < 0) {
                                round_bk_after_prin = 0;
                            }
                        }
                    }
                    else {
                        round_bk--;
                        if (round_bk < 0) {
                            round_bk = 0;
                        }
                    }
                }
                if (c == '[' && double_ic == false && single_ic == false && pair_ic == 0 && ts_has_ic == false && key_string_it[0] != key_string_end[0] - 1) {
                    if (prin == 1) {
                        square_bk_after_prin++;
                    }
                    else {
                        square_bk++;
                    }
                }
                if (c == ']' && double_ic == false && single_ic == false && pair_ic == 0 && ts_has_ic == false && square_bk > 0) {
                    if (prin == 1) {
                        if (square_bk_after_prin == 0) {
                            prin--;
                            if (prin < 0) {
                                prin = 0;
                            }
                        }
                        else {
                            square_bk_after_prin--;
                            if (square_bk_after_prin < 0) {
                                square_bk_after_prin = 0;
                            }
                        }
                    }
                    else {
                        square_bk--;
                        if (square_bk < 0) {
                            square_bk = 0;
                        }
                    }
                    square_bk--;
                    if (square_bk < 0) {
                        square_bk = 0;
                    }
                }
                if (c == '{' && double_ic == false && single_ic == false && pair_ic == 0 && ts_has_ic == false) {
                    figure_bk++;
                }
                if (c == '}' && double_ic == false && single_ic == false && pair_ic == 0 && ts_has_ic == false && figure_bk > 0) {
                    figure_bk--;
                    if (figure_bk < 0) {
                        figure_bk = 0;
                    }
                }
                for (int i = 0; i <= 4; i++) {
                    if (c == *key_string_it[i]) {
                        key_string_it[i]++;
                        if (key_string_it[i] == key_string_end[i] && double_ic == false && single_ic == false && pair_ic == 0 && ts_has_ic == false) {
                            switch (i) {
                            case 0:
                                if (prin < 1) {
                                    prin++;
                                }
                                if (prin > 1) {
                                    prin = 1;
                                }
                                break;
                            case 1:
                                conditions++;
                                break;
                            case 2:
                                if (conditions > 0) {
                                    conditions--;
                                }
                                if (conditions < 0) {
                                    conditions = 0;
                                }
                                break;
                            case 3:
                                cycles++;
                                break;
                            case 4:
                                if (cycles > 0) {
                                    cycles--;
                                }
                                if (cycles < 0) {
                                    cycles = 0;
                                }
                                break;
                            }
                        }
                        if (key_string_it[i] == key_string_end[i]) {
                            key_string_it[i] = key_string_begin[i];
                        }
                    }
                    else {
                        key_string_it[i] = key_string_begin[i];
                    }
                }
            }
            return string.substr(start, it - begin - start);
        }
Magic numbers все еще остались, не могу я без них... Что там еще? GOTO больше нет... Конкатенации строк в данном фрагменте также нет... Копирования строк вместо передачи по ссылке нет... Теперь можно назвать код если не хорошим, то как минимум сносным?

Полная хронология аллегорической книги:
Конечный автомат 2: Возвращение
Часть 1. Разбор
Глава 1. Общие положения
Глава 2. Число и слово
Глава 3. Пропуск и пропуск НИИК
Глава 4. Начало разбора
Глава 5. Вынос объявления
Глава 6. Действие
Глава 7. Условие
Глава 8. Имя, проверка строки и разбор до
Глава 9. Итераторы и третий вынос
Глава 10. Дела приватные
Глава 11. Битва титанов
...

По поводу ваших слов:
Цитата Сообщение от Usaga Посмотреть сообщение
Такие вещи принято выносить в константы или ресурсы (если поддерживается языком).
Имя константы намного длиннее, чем число, и на ее вычисление тратится время. Во всех отношениях, кроме "хорошего стиля", плохо.
Цитата Сообщение от Usaga Посмотреть сообщение
Валидация - проверка на соответствие требованиям. Она так же не должна изменять состояние.
Хорошо, чем заменить это слово, чтобы можно было изменять состояние?
Цитата Сообщение от Usaga Посмотреть сообщение
Да, знаю. Делать эту проверку перед вызовом метода. И !is_end() ещё короче.
Возможно, разберусь с этим в главе 12...

И поступайте как хотите, но все же очень хотелось бы прочитать ваше мнение по поводу этого сообщения. Где в моих словах - неправда и сколько вы можете назвать недостатков DCASTF, которые реально мешают программировать и которых нет в C++/C#?

Добавлено через 1 час 25 минут
Что-то в последнее время вы стали намного реже комментировать мои сообщения, раньше бывало по десять раз в день не предел, сейчас редко три. Почему так?
0
Эксперт .NET
9326 / 6689 / 1081
Регистрация: 21.01.2016
Сообщений: 25,207
08.01.2019, 18:36 16
Etyuhibosecyu, воспользуйтесь уже каким-нибудь генератором парсеров. Опишите грамматику вашего языка (заодно её придумаете) и получите исходник на С++ для разбора вашего языка. Это будет в 100500 раз быстрее и качественнее.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
И поступайте как хотите, но все же очень хотелось бы прочитать ваше мнение по поводу этого сообщения. Где в моих словах - неправда и сколько вы можете назвать недостатков DCASTF, которые реально мешают программировать и которых нет в C++/C#?
Мы это уже обсосали со всех сторон. Единственный повод подтолкнувший вас к созданию нечта под названием DCASFT - обострение синдрома NIH (Not Invented Here) вкупе с полным незнанием С++ (или чем вы там до этого пользовались). Т.е. вы не недостатки С++\С# исправляете, вы своё незнание этих языков компенсируете переизобретением всего, что только можно. Когда вы наткнулись на что-то вам неудобное (или отсутствие удобства), вместо того, чтобы пойти и поискать как и чем это заменяется\реализуется, вы решили, что этого нет и это срочно нужно изобрести.

Более того, я от вас битый час не мог добиться внятного описания, что есть DCASFT. Не то компилятор, не то транслятор, не то платформа целая, не то IDE или набор мастеров. Настолько у вас всё плохо было с пониманием предметной области. Из этого следует простой вывод, который я вам уже несколько раз прямо озвучивал: вы не сможете сделать даже игрушечный язык, не то, что "профессиональный инструмент", пока не освоите тот же самый С++ (к которому у вас претензии) и все сопутствующие вещи (алгоритмы, приёмы, подходы, технологии) хотя бы на уровне "4+".

Ваш текущий подход - метод тыка и переизобретение колёс. Вы знаете, что есть документация по С++, с огромным количеством информации как по самому языку, так и по базовой библиотеке классов. Но, судя по "коду" выше, упорно её игнорируете. Вы про контейнеры из STL-то только-только узнали. Да и то, про один единственный. Профессиональный подход, да?

Я не против того, чтобы вы своё личное время в пустую выкидывали изобретая мусор с нулевой отдачей в плане самообразования. Дело ваше. Но делать необоснованные (у вас нет компетенции позволяющей это делать) заявления о том, что тот же С++ не обладает достаточным функционалом для реализации приложения любой сложности не надо. Это провоцирует на срачи.

Цитата Сообщение от Etyuhibosecyu Посмотреть сообщение
Что-то в последнее время вы стали намного реже комментировать мои сообщения, раньше бывало по десять раз в день не предел, сейчас редко три. Почему так?
Я уже об этом говорил: я потерял интерес к вашим темам. Тут всё одно, да по одному. Я вас снабдил всей необходимой вам информацией. Как минимум, рассказал про Гугл, где вы можете нарыть всё: полные справочники по С++\C#, алгоритмам, приёмам, технологиям, подходам, учебники на любую тему, ВООБЩЕ ВСЁ.

Хотите узнать, что в С++ хреново? Изучите С++ досконально! Хотите написать свой компилятор или транслятор? Ну так теоретического материала (как и примеров кода на всех возможных языках) в сети ТОННЫ. Кто вам мешает изучить вопрос создания синтаксического анализатора? Никто.

А так, это игра с куличиками в песочнице.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.01.2019, 18:36

Ошибка в конструкторе: "Файл не поддерживает синтаксический разбор кода"
как это можно исправить?

Задачи и решения к задачам на тему "Грамматический разбор"
Доброго времени суток.Большая просьба, может кто подскажет какие-нибудь задачи и решения к задачам...

Ошибка "Проект не поддерживает синтаксический разбор кода или его автоматическое создание"
При создании проекта в программе Visual Basic 2008 или Visual Basic 2010 выбивает ошибка. Помогите...

Как в билдере получить с сервера (MySQL 5.1, имя базы "skola", имя table "info") имя столбцов и имя строк
Доброва времены суток Как в билдере получить с сервера (MySQL 5.1, имя базы &quot;skola&quot;, имя table...

Разбор "полетов" по потоку Thread
наткнулся на статейку на сайте https://habr.com/company/nixsolutions/blog/260745/ и у меня...

Задача на тему "Разбор строк"
Задача на тему &quot;Разбор строк&quot;, поэтому просто считываем две строки. В цикле сравниваем символы,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.