llama

Форк
0
/
test-grammar-parser.cpp 
517 строк · 16.4 Кб
1
#ifdef NDEBUG
2
#undef NDEBUG
3
#endif
4

5
#include "llama.h"
6
#include "llama-grammar.h"
7

8
#include <cassert>
9

10
static const char * type_str(llama_gretype type) {
11
    switch (type) {
12
        case LLAMA_GRETYPE_CHAR: return "LLAMA_GRETYPE_CHAR";
13
        case LLAMA_GRETYPE_CHAR_NOT: return "LLAMA_GRETYPE_CHAR_NOT";
14
        case LLAMA_GRETYPE_CHAR_ALT: return "LLAMA_GRETYPE_CHAR_ALT";
15
        case LLAMA_GRETYPE_CHAR_RNG_UPPER: return "LLAMA_GRETYPE_CHAR_RNG_UPPER";
16
        case LLAMA_GRETYPE_RULE_REF: return "LLAMA_GRETYPE_RULE_REF";
17
        case LLAMA_GRETYPE_ALT: return "LLAMA_GRETYPE_ALT";
18
        case LLAMA_GRETYPE_END: return "LLAMA_GRETYPE_END";
19
        default: return "?";
20
    }
21
}
22

23
static void verify_parsing(const char *grammar_bytes, const std::vector<std::pair<std::string, uint32_t>> expected, const std::vector<llama_grammar_element> &expected_rules) {
24
    uint32_t index = 0;
25
    llama_grammar_parser parsed_grammar;
26
    parsed_grammar.parse(grammar_bytes);
27

28
    std::map<uint32_t, std::string> symbol_names;
29
    for (auto it = parsed_grammar.symbol_ids.begin(); it != parsed_grammar.symbol_ids.end(); ++it) {
30
        symbol_names[it->second] = it->first;
31
    }
32

33
    auto print_all = [&]() {
34
        fprintf(stderr, "    verify_parsing(R\"\"\"(%s)\"\"\", {\n", grammar_bytes);
35
        for (auto it = parsed_grammar.symbol_ids.begin(); it != parsed_grammar.symbol_ids.end(); ++it) {
36
            fprintf(stderr, "        {\"%s\", %u},\n", it->first.c_str(), it->second);
37
        }
38
        fprintf(stderr, "    }, {\n");
39
        for (size_t i_rule = 0; i_rule < parsed_grammar.rules.size(); i_rule++) {
40
            fprintf(stderr, "        // %s (index %zu)\n", symbol_names[i_rule].c_str(), i_rule);
41
            auto & rule = parsed_grammar.rules[i_rule];
42
            for (uint32_t i = 0; i < rule.size(); i++) {
43
                std::string rule_str;
44
                fprintf(stderr, "        {%s, ", type_str(rule[i].type));
45
                if (rule[i].type == LLAMA_GRETYPE_CHAR || rule[i].type == LLAMA_GRETYPE_CHAR_ALT ||
46
                    rule[i].type == LLAMA_GRETYPE_CHAR_NOT || rule[i].type == LLAMA_GRETYPE_CHAR_RNG_UPPER) {
47
                    char c = rule[i].value;
48
                    if (c == '\n') {
49
                        fprintf(stderr, "'\\n'");
50
                    } else if (c == '\t') {
51
                        fprintf(stderr, "'\\t'");
52
                    } else if (c == '\r') {
53
                        fprintf(stderr, "'\\r'");
54
                    } else if (c == '\0') {
55
                        fprintf(stderr, "'\\0'");
56
                    } else {
57
                        fprintf(stderr, "'%c'", c);
58
                    }
59
                } else if (rule[i].type == LLAMA_GRETYPE_RULE_REF) {
60
                    fprintf(stderr, "/* %s */ %u", symbol_names[rule[i].value].c_str(), rule[i].value);
61
                } else {
62
                    fprintf(stderr, "%u", rule[i].value);
63
                }
64
                fprintf(stderr, "},\n");
65
            }
66
        }
67
        fprintf(stderr, "    });\n");
68
    };
69

70
    if (getenv("TEST_GRAMMAR_PARSER_PRINT_ALL")) {
71
        print_all();
72
        fprintf(stderr, "\n");
73
        return;
74
    }
75

76
    fprintf(stderr, "Testing grammar:%s\n", grammar_bytes);
77

78
    if (parsed_grammar.symbol_ids.size() != expected.size()) {
79
        fprintf(stderr, "Code to update expectation (set TEST_GRAMMAR_PARSER_PRINT_ALL=1 to print all):\n");
80
        print_all();
81
        assert(parsed_grammar.symbol_ids.size() == expected.size());
82
    }
83

84
    for (auto it = parsed_grammar.symbol_ids.begin(); it != parsed_grammar.symbol_ids.end(); ++it)
85
    {
86
        std::string key = it->first;
87
        uint32_t value = it->second;
88
        std::pair<std::string, uint32_t> expected_pair = expected[index];
89

90
        // pretty print error message before asserting
91
        if (expected_pair.first != key || expected_pair.second != value)
92
        {
93
            fprintf(stderr, "index: %u\n", index);
94
            fprintf(stderr, "expected_pair: %s, %u\n", expected_pair.first.c_str(), expected_pair.second);
95
            fprintf(stderr, "actual_pair: %s, %u\n", key.c_str(), value);
96
            fprintf(stderr, "expected_pair != actual_pair\n");
97
            fprintf(stderr, "Code to update expectation (set TEST_GRAMMAR_PARSER_PRINT_ALL=1 to print all):\n");
98
            print_all();
99
        }
100

101
        assert(expected_pair.first == key && expected_pair.second == value);
102

103
        index++;
104
    }
105

106
    index = 0;
107
    for (auto rule : parsed_grammar.rules)
108
    {
109
        // compare rule to expected rule
110
        for (uint32_t i = 0; i < rule.size(); i++)
111
        {
112
            llama_grammar_element element = rule[i];
113
            llama_grammar_element expected_element = expected_rules[index];
114

115
            // pretty print error message before asserting
116
            if (expected_element.type != element.type || expected_element.value != element.value)
117
            {
118
                fprintf(stderr, "index: %u\n", index);
119
                fprintf(stderr, "expected_element: %s, %u\n", type_str(expected_element.type), expected_element.value);
120
                fprintf(stderr, "actual_element: %s, %u\n", type_str(element.type), element.value);
121
                fprintf(stderr, "expected_element != actual_element\n");
122
                fprintf(stderr, "all elements:\n");
123
                fprintf(stderr, "Code to update expectation (set TEST_GRAMMAR_PARSER_PRINT_ALL=1 to print all):\n");
124
                print_all();
125
            }
126

127
            assert(expected_element.type == element.type && expected_element.value == element.value);
128
            index++;
129
        }
130
    }
131
}
132

133
static void verify_failure(const char * grammar_bytes) {
134
    fprintf(stderr, "Testing expected failure:%s\n", grammar_bytes);
135
    llama_grammar_parser result;
136
    result.parse(grammar_bytes);
137
    assert(result.rules.empty() && "should have failed");
138
}
139

140
int main()
141
{
142
    verify_failure(R"""(
143
        root ::= "a"{,}"
144
    )""");
145

146
    verify_failure(R"""(
147
        root ::= "a"{,10}"
148
    )""");
149

150
    verify_parsing(R"""(
151
        root  ::= "a"
152
    )""", {
153
        {"root", 0},
154
    }, {
155
        // root (index 0)
156
        {LLAMA_GRETYPE_CHAR, 'a'},
157
        {LLAMA_GRETYPE_END, 0},
158
    });
159

160
    verify_parsing(R"""(
161
        root  ::= "a" | [bdx-z] | [^1-3]
162
    )""", {
163
        {"root", 0},
164
    }, {
165
        // root (index 0)
166
        {LLAMA_GRETYPE_CHAR, 'a'},
167
        {LLAMA_GRETYPE_ALT, 0},
168
        {LLAMA_GRETYPE_CHAR, 'b'},
169
        {LLAMA_GRETYPE_CHAR_ALT, 'd'},
170
        {LLAMA_GRETYPE_CHAR_ALT, 'x'},
171
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, 'z'},
172
        {LLAMA_GRETYPE_ALT, 0},
173
        {LLAMA_GRETYPE_CHAR_NOT, '1'},
174
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, '3'},
175
        {LLAMA_GRETYPE_END, 0},
176
    });
177

178
    verify_parsing(R"""(
179
        root  ::= a+
180
        a     ::= "a"
181
    )""", {
182
        {"a", 1},
183
        {"root", 0},
184
        {"root_2", 2},
185
    }, {
186
        // root (index 0)
187
        {LLAMA_GRETYPE_RULE_REF, /* a */ 1},
188
        {LLAMA_GRETYPE_RULE_REF, /* root_2 */ 2},
189
        {LLAMA_GRETYPE_END, 0},
190
        // a (index 1)
191
        {LLAMA_GRETYPE_CHAR, 'a'},
192
        {LLAMA_GRETYPE_END, 0},
193
        // root_2 (index 2)
194
        {LLAMA_GRETYPE_RULE_REF, /* a */ 1},
195
        {LLAMA_GRETYPE_RULE_REF, /* root_2 */ 2},
196
        {LLAMA_GRETYPE_ALT, 0},
197
        {LLAMA_GRETYPE_END, 0},
198
    });
199

200
    verify_parsing(R"""(
201
        root  ::= "a"+
202
    )""", {
203
        {"root", 0},
204
        {"root_1", 1},
205
    }, {
206
        // root (index 0)
207
        {LLAMA_GRETYPE_CHAR, 'a'},
208
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
209
        {LLAMA_GRETYPE_END, 0},
210
        // root_1 (index 1)
211
        {LLAMA_GRETYPE_CHAR, 'a'},
212
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
213
        {LLAMA_GRETYPE_ALT, 0},
214
        {LLAMA_GRETYPE_END, 0},
215
    });
216

217
    verify_parsing(R"""(
218
        root  ::= a?
219
        a     ::= "a"
220
    )""", {
221
        {"a", 1},
222
        {"root", 0},
223
        {"root_2", 2},
224
    }, {
225
        // root (index 0)
226
        {LLAMA_GRETYPE_RULE_REF, /* root_2 */ 2},
227
        {LLAMA_GRETYPE_END, 0},
228
        // a (index 1)
229
        {LLAMA_GRETYPE_CHAR, 'a'},
230
        {LLAMA_GRETYPE_END, 0},
231
        // root_2 (index 2)
232
        {LLAMA_GRETYPE_RULE_REF, /* a */ 1},
233
        {LLAMA_GRETYPE_ALT, 0},
234
        {LLAMA_GRETYPE_END, 0},
235
    });
236

237
    verify_parsing(R"""(
238
        root  ::= "a"?
239
    )""", {
240
        {"root", 0},
241
        {"root_1", 1},
242
    }, {
243
        // root (index 0)
244
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
245
        {LLAMA_GRETYPE_END, 0},
246
        // root_1 (index 1)
247
        {LLAMA_GRETYPE_CHAR, 'a'},
248
        {LLAMA_GRETYPE_ALT, 0},
249
        {LLAMA_GRETYPE_END, 0},
250
    });
251

252
    verify_parsing(R"""(
253
        root  ::= a*
254
        a     ::= "a"
255
    )""", {
256
        {"a", 1},
257
        {"root", 0},
258
        {"root_2", 2},
259
    }, {
260
        // root (index 0)
261
        {LLAMA_GRETYPE_RULE_REF, /* root_2 */ 2},
262
        {LLAMA_GRETYPE_END, 0},
263
        // a (index 1)
264
        {LLAMA_GRETYPE_CHAR, 'a'},
265
        {LLAMA_GRETYPE_END, 0},
266
        // root_2 (index 2)
267
        {LLAMA_GRETYPE_RULE_REF, /* a */ 1},
268
        {LLAMA_GRETYPE_RULE_REF, /* root_2 */ 2},
269
        {LLAMA_GRETYPE_ALT, 0},
270
        {LLAMA_GRETYPE_END, 0},
271
    });
272

273
    verify_parsing(R"""(
274
        root  ::= "a"*
275
    )""", {
276
        {"root", 0},
277
        {"root_1", 1},
278
    }, {
279
        // root (index 0)
280
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
281
        {LLAMA_GRETYPE_END, 0},
282
        // root_1 (index 1)
283
        {LLAMA_GRETYPE_CHAR, 'a'},
284
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
285
        {LLAMA_GRETYPE_ALT, 0},
286
        {LLAMA_GRETYPE_END, 0},
287
    });
288

289
    verify_parsing(R"""(
290
        root  ::= "a"{2}
291
    )""", {
292
        {"root", 0},
293
    }, {
294
        // root (index 0)
295
        {LLAMA_GRETYPE_CHAR, 'a'},
296
        {LLAMA_GRETYPE_CHAR, 'a'},
297
        {LLAMA_GRETYPE_END, 0},
298
    });
299

300
    verify_parsing(R"""(
301
        root  ::= "a"{2,}
302
    )""", {
303
        {"root", 0},
304
        {"root_1", 1},
305
    }, {
306
        // root (index 0)
307
        {LLAMA_GRETYPE_CHAR, 'a'},
308
        {LLAMA_GRETYPE_CHAR, 'a'},
309
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
310
        {LLAMA_GRETYPE_END, 0},
311
        // root_1 (index 1)
312
        {LLAMA_GRETYPE_CHAR, 'a'},
313
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
314
        {LLAMA_GRETYPE_ALT, 0},
315
        {LLAMA_GRETYPE_END, 0},
316
    });
317

318
    verify_parsing(R"""(
319
        root  ::= "a"{ 4}
320
    )""", {
321
        {"root", 0},
322
    }, {
323
        // root (index 0)
324
        {LLAMA_GRETYPE_CHAR, 'a'},
325
        {LLAMA_GRETYPE_CHAR, 'a'},
326
        {LLAMA_GRETYPE_CHAR, 'a'},
327
        {LLAMA_GRETYPE_CHAR, 'a'},
328
        {LLAMA_GRETYPE_END, 0},
329
    });
330

331
    verify_parsing(R"""(
332
        root  ::= "a"{2,4}
333
    )""", {
334
        {"root", 0},
335
        {"root_1", 1},
336
        {"root_2", 2},
337
    }, {
338
        // root (index 0)
339
        {LLAMA_GRETYPE_CHAR, 'a'},
340
        {LLAMA_GRETYPE_CHAR, 'a'},
341
        {LLAMA_GRETYPE_RULE_REF, /* root_2 */ 2},
342
        {LLAMA_GRETYPE_END, 0},
343
        // root_1 (index 1)
344
        {LLAMA_GRETYPE_CHAR, 'a'},
345
        {LLAMA_GRETYPE_ALT, 0},
346
        {LLAMA_GRETYPE_END, 0},
347
        // root_2 (index 2)
348
        {LLAMA_GRETYPE_CHAR, 'a'},
349
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
350
        {LLAMA_GRETYPE_ALT, 0},
351
        {LLAMA_GRETYPE_END, 0},
352
    });
353

354
    verify_parsing(R"""(
355
        root  ::= (expr "=" term "\n")+
356
        expr  ::= term ([-+*/] term)*
357
        term  ::= [0-9]+
358
    )""", {
359
        {"expr", 2},
360
        {"expr_5", 5},
361
        {"expr_6", 6},
362
        {"root", 0},
363
        {"root_1", 1},
364
        {"root_4", 4},
365
        {"term", 3},
366
        {"term_7", 7},
367
    }, {
368
        // root (index 0)
369
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
370
        {LLAMA_GRETYPE_RULE_REF, /* root_4 */ 4},
371
        {LLAMA_GRETYPE_END, 0},
372
        // root_1 (index 1)
373
        {LLAMA_GRETYPE_RULE_REF, /* expr */ 2},
374
        {LLAMA_GRETYPE_CHAR, '='},
375
        {LLAMA_GRETYPE_RULE_REF, /* term */ 3},
376
        {LLAMA_GRETYPE_CHAR, '\n'},
377
        {LLAMA_GRETYPE_END, 0},
378
        // expr (index 2)
379
        {LLAMA_GRETYPE_RULE_REF, /* term */ 3},
380
        {LLAMA_GRETYPE_RULE_REF, /* expr_6 */ 6},
381
        {LLAMA_GRETYPE_END, 0},
382
        // term (index 3)
383
        {LLAMA_GRETYPE_CHAR, '0'},
384
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, '9'},
385
        {LLAMA_GRETYPE_RULE_REF, /* term_7 */ 7},
386
        {LLAMA_GRETYPE_END, 0},
387
        // root_4 (index 4)
388
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
389
        {LLAMA_GRETYPE_RULE_REF, /* root_4 */ 4},
390
        {LLAMA_GRETYPE_ALT, 0},
391
        {LLAMA_GRETYPE_END, 0},
392
        // expr_5 (index 5)
393
        {LLAMA_GRETYPE_CHAR, '-'},
394
        {LLAMA_GRETYPE_CHAR_ALT, '+'},
395
        {LLAMA_GRETYPE_CHAR_ALT, '*'},
396
        {LLAMA_GRETYPE_CHAR_ALT, '/'},
397
        {LLAMA_GRETYPE_RULE_REF, /* term */ 3},
398
        {LLAMA_GRETYPE_END, 0},
399
        // expr_6 (index 6)
400
        {LLAMA_GRETYPE_RULE_REF, /* expr_5 */ 5},
401
        {LLAMA_GRETYPE_RULE_REF, /* expr_6 */ 6},
402
        {LLAMA_GRETYPE_ALT, 0},
403
        {LLAMA_GRETYPE_END, 0},
404
        // term_7 (index 7)
405
        {LLAMA_GRETYPE_CHAR, '0'},
406
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, '9'},
407
        {LLAMA_GRETYPE_RULE_REF, /* term_7 */ 7},
408
        {LLAMA_GRETYPE_ALT, 0},
409
        {LLAMA_GRETYPE_END, 0},
410
    });
411

412
    verify_parsing(R"""(
413
        root  ::= (expr "=" ws term "\n")+
414
        expr  ::= term ([-+*/] term)*
415
        term  ::= ident | num | "(" ws expr ")" ws
416
        ident ::= [a-z] [a-z0-9_]* ws
417
        num   ::= [0-9]+ ws
418
        ws    ::= [ \t\n]*
419
    )""", {
420
        {"expr", 2},
421
        {"expr_6", 6},
422
        {"expr_7", 7},
423
        {"ident", 8},
424
        {"ident_10", 10},
425
        {"num", 9},
426
        {"num_11", 11},
427
        {"root", 0},
428
        {"root_1", 1},
429
        {"root_5", 5},
430
        {"term", 4},
431
        {"ws", 3},
432
        {"ws_12", 12},
433
    }, {
434
        // root (index 0)
435
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
436
        {LLAMA_GRETYPE_RULE_REF, /* root_5 */ 5},
437
        {LLAMA_GRETYPE_END, 0},
438
        // root_1 (index 1)
439
        {LLAMA_GRETYPE_RULE_REF, /* expr */ 2},
440
        {LLAMA_GRETYPE_CHAR, '='},
441
        {LLAMA_GRETYPE_RULE_REF, /* ws */ 3},
442
        {LLAMA_GRETYPE_RULE_REF, /* term */ 4},
443
        {LLAMA_GRETYPE_CHAR, '\n'},
444
        {LLAMA_GRETYPE_END, 0},
445
        // expr (index 2)
446
        {LLAMA_GRETYPE_RULE_REF, /* term */ 4},
447
        {LLAMA_GRETYPE_RULE_REF, /* expr_7 */ 7},
448
        {LLAMA_GRETYPE_END, 0},
449
        // ws (index 3)
450
        {LLAMA_GRETYPE_RULE_REF, /* ws_12 */ 12},
451
        {LLAMA_GRETYPE_END, 0},
452
        // term (index 4)
453
        {LLAMA_GRETYPE_RULE_REF, /* ident */ 8},
454
        {LLAMA_GRETYPE_ALT, 0},
455
        {LLAMA_GRETYPE_RULE_REF, /* num */ 9},
456
        {LLAMA_GRETYPE_ALT, 0},
457
        {LLAMA_GRETYPE_CHAR, '('},
458
        {LLAMA_GRETYPE_RULE_REF, /* ws */ 3},
459
        {LLAMA_GRETYPE_RULE_REF, /* expr */ 2},
460
        {LLAMA_GRETYPE_CHAR, ')'},
461
        {LLAMA_GRETYPE_RULE_REF, /* ws */ 3},
462
        {LLAMA_GRETYPE_END, 0},
463
        // root_5 (index 5)
464
        {LLAMA_GRETYPE_RULE_REF, /* root_1 */ 1},
465
        {LLAMA_GRETYPE_RULE_REF, /* root_5 */ 5},
466
        {LLAMA_GRETYPE_ALT, 0},
467
        {LLAMA_GRETYPE_END, 0},
468
        // expr_6 (index 6)
469
        {LLAMA_GRETYPE_CHAR, '-'},
470
        {LLAMA_GRETYPE_CHAR_ALT, '+'},
471
        {LLAMA_GRETYPE_CHAR_ALT, '*'},
472
        {LLAMA_GRETYPE_CHAR_ALT, '/'},
473
        {LLAMA_GRETYPE_RULE_REF, /* term */ 4},
474
        {LLAMA_GRETYPE_END, 0},
475
        // expr_7 (index 7)
476
        {LLAMA_GRETYPE_RULE_REF, /* expr_6 */ 6},
477
        {LLAMA_GRETYPE_RULE_REF, /* expr_7 */ 7},
478
        {LLAMA_GRETYPE_ALT, 0},
479
        {LLAMA_GRETYPE_END, 0},
480
        // ident (index 8)
481
        {LLAMA_GRETYPE_CHAR, 'a'},
482
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, 'z'},
483
        {LLAMA_GRETYPE_RULE_REF, /* ident_10 */ 10},
484
        {LLAMA_GRETYPE_RULE_REF, /* ws */ 3},
485
        {LLAMA_GRETYPE_END, 0},
486
        // num (index 9)
487
        {LLAMA_GRETYPE_CHAR, '0'},
488
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, '9'},
489
        {LLAMA_GRETYPE_RULE_REF, /* num_11 */ 11},
490
        {LLAMA_GRETYPE_RULE_REF, /* ws */ 3},
491
        {LLAMA_GRETYPE_END, 0},
492
        // ident_10 (index 10)
493
        {LLAMA_GRETYPE_CHAR, 'a'},
494
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, 'z'},
495
        {LLAMA_GRETYPE_CHAR_ALT, '0'},
496
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, '9'},
497
        {LLAMA_GRETYPE_CHAR_ALT, '_'},
498
        {LLAMA_GRETYPE_RULE_REF, /* ident_10 */ 10},
499
        {LLAMA_GRETYPE_ALT, 0},
500
        {LLAMA_GRETYPE_END, 0},
501
        // num_11 (index 11)
502
        {LLAMA_GRETYPE_CHAR, '0'},
503
        {LLAMA_GRETYPE_CHAR_RNG_UPPER, '9'},
504
        {LLAMA_GRETYPE_RULE_REF, /* num_11 */ 11},
505
        {LLAMA_GRETYPE_ALT, 0},
506
        {LLAMA_GRETYPE_END, 0},
507
        // ws_12 (index 12)
508
        {LLAMA_GRETYPE_CHAR, ' '},
509
        {LLAMA_GRETYPE_CHAR_ALT, '\t'},
510
        {LLAMA_GRETYPE_CHAR_ALT, '\n'},
511
        {LLAMA_GRETYPE_RULE_REF, /* ws_12 */ 12},
512
        {LLAMA_GRETYPE_ALT, 0},
513
        {LLAMA_GRETYPE_END, 0},
514
    });
515

516
    return 0;
517
}
518

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.