loom

Форк
0
/
main.cpp 
300 строк · 12.7 Кб
1
/*
2
MIT License
3

4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
5

6
https://bmstu.codes/lsx/simodo/loom
7
*/
8

9
/*! \file Интерпретация текста
10
 *
11
 *  Утилита интерпретации текста на любом языке, заданном грамматикой на языке SIMODO fuze.
12
 *
13
 *  Проект SIMODO.
14
*/
15

16
#include "simodo/interpret/SemanticModuleFactory_interface.h"
17

18
#include "simodo/inout/reporter/ConsoleReporter.h"
19
#include "simodo/inout/convert/functions.h"
20
#include "simodo/interpret/InterpretType.h"
21
#include "simodo/module/ModuleManagement.h"
22
#include "simodo/inout/token/RegularInputStreamSupplier.h"
23
#include "simodo/LibVersion.h"
24

25
#include <string>
26
#include <vector>
27
#include <functional>
28
#include <iostream>
29
#include <fstream>
30
#include <memory>
31
#include <algorithm>
32
#include <chrono>
33

34
#if __cplusplus >= __cpp_2017
35
#include <filesystem>
36
namespace fs = std::filesystem;
37
#else
38
#include <experimental/filesystem>
39
namespace fs = std::filesystem::experimental;
40
#endif
41

42
#include <boost/dll/import.hpp>
43

44
namespace dll = boost::dll;
45

46
using namespace simodo;
47

48
static const std::string DIGITS = "0123456789";
49

50
int main(int argc, char *argv[])
51
{
52
    std::vector<std::string> arguments(argv + 1, argv + argc);
53

54
    std::string                 file_name           = "";
55
    std::vector<std::string>    interpret_places;
56
    std::vector<std::string>    hard_module_places;
57
    std::vector<std::string>    grammar_places;
58
    std::vector<std::string>    preload_module_names;
59
    bool                        need_time_intervals = false;
60
    bool	                    error               = false;
61
    bool	                    help                = false;
62
    bool	                    version             = false;
63
    bool                        need_silence        = false;
64
    std::string                 type_string         = "";
65
    std::string                 initial_contracts_file = module::INITIAL_CONTRACTS_FILE;
66
    bool                        debug_mode          = false;
67
    uint64_t                    timeout             = 0;
68
    bool                        resume              = true;
69
    bool                        need_full_debug_info= false;
70
    std::vector<interpret::BreakPoint> breakpoints;
71

72
    for(size_t i=0; i < arguments.size(); ++i)
73
    {
74
        const std::string & arg = arguments[i];
75

76
        if (arg[0] == '-')
77
        {
78
            if (arg == "--help" || arg == "-h")
79
                help = true;
80
            else if (arg == "--version" || arg == "-v")
81
                version = true;
82
            else if (arg == "--type" || arg == "-p")
83
            {
84
                if (i == arguments.size()-1 || !type_string.empty())
85
                    error = true;
86
                else
87
                    type_string = arguments[++i];
88
            }
89
            else if (arg == "--semantics-dir" || arg == "-s")
90
            {
91
                if (i == arguments.size()-1)
92
                    error = true;
93
                else
94
                    interpret_places.push_back(arguments[++i]);
95
            }
96
            else if (arg == "--hard-modules-dir" || arg == "-a")
97
            {
98
                if (i == arguments.size()-1)
99
                    error = true;
100
                else
101
                    hard_module_places.push_back(arguments[++i]);
102
            }
103
            else if (arg == "--preload-module" || arg == "-m")
104
            {
105
                if (i == arguments.size()-1)
106
                    error = true;
107
                else
108
                    preload_module_names.push_back(arguments[++i]);
109
            }
110
            else if (arg == "--grammars-dir" || arg == "-g")
111
            {
112
                if (i == arguments.size()-1)
113
                    error = true;
114
                else
115
                    grammar_places.push_back(arguments[++i]);
116
            }
117
            else if (arg == "--initial-contracts-file" || arg == "-c")
118
            {
119
                if (i == arguments.size()-1)
120
                    error = true;
121
                else
122
                    initial_contracts_file = arguments[++i];
123
            }
124
            else if (arg == "--time-intervals" || arg == "-t")
125
                need_time_intervals = true;
126
            else if (arg == "--silence" || arg == "-S")
127
                need_silence = true;
128
            else if (arg == "--stop") {
129
                resume = false;
130
                debug_mode = true;
131
                if (i != arguments.size()-1 && DIGITS.find(arguments[i+1][0]) != std::string::npos) {
132
                    ++i;
133
                    timeout = std::stoul(arguments[i]);
134
                }
135
            }
136
            else if (arg == "--debug" || arg == "-d") {
137
                debug_mode = true;
138
                if (i != arguments.size()-1 && DIGITS.find(arguments[i+1][0]) != std::string::npos) {
139
                    ++i;
140
                    timeout = std::stoul(arguments[i]);
141
                }
142
            }
143
            else if (arg == "--full-debug-info" || arg == "-f") {
144
                need_full_debug_info = true;
145
                debug_mode = true;
146
            }
147
            else if (arg == "--breakpoint" || arg == "-b") {
148
                debug_mode = true;
149
                resume = false;
150
                if (i == arguments.size()-1)
151
                    error = true;
152
                else {
153
                    ++i;
154
                    bool line_first = true;
155
                    for(const auto & c : arguments[i])
156
                        if (DIGITS.find(c) == std::string::npos) {
157
                            line_first = false;
158
                            break;
159
                        }
160
                    if (line_first)
161
                        breakpoints.push_back({file_name, inout::position_line_t(std::stoul(arguments[i]))});
162
                    else if (i == arguments.size()-1)
163
                        error = true;
164
                    else {
165
                        std::string uri = arguments[i];
166
                        ++i;
167

168
                        bool line_second = true;
169
                        for(const auto & c : arguments[i])
170
                            if (DIGITS.find(c) == std::string::npos) {
171
                                line_second = false;
172
                                break;
173
                            }
174
                        if (line_second)
175
                            breakpoints.push_back({uri, inout::position_line_t(std::stoul(arguments[i]))});
176
                        else
177
                            error = true;
178
                    }
179
                }
180
            }
181
            else
182
                error = true;
183
        }
184
        else if (file_name.empty())
185
            file_name = arg;
186
        else
187
            error = true;
188
    }
189

190
    interpret::InterpretType interpret_type = interpret::InterpretType::Preview;
191

192
    if (type_string == "analyze" || type_string == "a")
193
        interpret_type = interpret::InterpretType::Analyzer;
194
    else if (type_string == "preview" || type_string == "v")
195
        interpret_type = interpret::InterpretType::Preview;
196
    else if (!type_string.empty()) {
197
        std::cout << "Задан недопустимый тип интерпретации" << std::endl;
198
        error = true;
199
    }
200

201
    if (file_name.empty() && !version && !help)
202
        error = true;
203

204
    if (error) {
205
        std::cout << "Ошибка в параметрах запуска" << std::endl;
206
        help = true;
207
    }
208

209
    const std::string logo = "Утилита интерпретации. Проект SIMODO.";
210

211
    {
212
        using namespace std;
213

214
        if (help)
215
            cout	<< logo << endl
216
                    << "Формат запуска:" << endl
217
                    << "    simodo-interpret [<параметры>] <файл>" << endl
218
                    << "Параметры:" << endl
219
                    << "    -h | --help                       - отображение подсказки по запуску программы" << endl
220
                    << "    -v | --version                    - отображение версии программы" << endl
221
                    << "    -p | --type {a|v|analyze|preview} - тип интерпретации (по умолчанию: run)" << endl
222
                    << "    -s | --semantics-dir <путь>       - путь к интерпретаторам (по умолчанию: bin/semantics)" << endl
223
                    << "    -a | --hard-modules-dir <путь>    - путь к каталогу жёстких модулей (по умолчанию: bin/modules)" << endl
224
                    << "    -g | --grammars-dir <путь>        - путь к каталогу грамматик (по умолчанию: data/grammar)" << endl
225
                    << "    -c | --initial-contracts-file <путь> - путь к файлу обязательных контрактов" << endl
226
                    << "                                           (по умолчанию: initial-contracts.simodo-script)," << endl
227
                    << "                                           должен находиться в каталоге: data/grammar/contracts" << endl
228
                    << "    -m | --preload-module <имя>       - имя модуля для предварительно загрузки (можно указать несколько раз)" << endl
229
                    << "    -t | --time-intervals             - отображать интервалы времени разбора" << endl
230
                    << "    -d | --debug [<timeout>]          - режим отладки и timeout для остановки по времени (в секундах)" << endl
231
                    << "       | --stop [<timeout>]           - прекращать работу после остановки по истечению времени (в секундах)" << endl
232
                    << "    -f | --full-debug-info            - выводить полную информацию по всем рабочим нитям" << endl
233
                    << "    -b | --breakpoint [<file>] <line> - установить точку останова (можно задавать многократно)" << endl
234
                    << "    -S | --silence                    - не выводить диагностику утилиты" << endl
235
                    ;
236
    }
237

238
    if (error)
239
        return 1;
240

241
    if (version)
242
        std::cout << logo << std::endl
243
             << "Версия: " << lib_version().major() << "." << lib_version().minor() << std::endl;
244

245
    if (file_name.empty())
246
        return 0;
247

248
    if (interpret_places.empty())
249
        interpret_places.push_back("bin/semantics");
250

251
    if (hard_module_places.empty())
252
        hard_module_places.push_back("bin/modules");
253

254
    if (grammar_places.empty())
255
        grammar_places.push_back("data/grammar");
256

257
    if (!initial_contracts_file.empty()) {
258
        fs::path initial_contracts_path = fs::path(grammar_places[0])
259
                                / fs::path(module::INITIAL_CONTRACTS_DIR) 
260
                                / fs::path(module::INITIAL_CONTRACTS_FILE);
261
        initial_contracts_file = initial_contracts_path.string();
262
    }
263

264
    inout::ConsoleReporter            r;
265
    inout::RegularInputStreamSupplier file_supplier;
266
    interpret::SemanticDataCollector_null semantic_data;
267
    module::ModuleManagement          mm(   r, 
268
                                            file_supplier, 
269
                                            interpret_places,
270
                                            hard_module_places, 
271
                                            grammar_places, 
272
                                            interpret_type,
273
                                            semantic_data,
274
                                            std::cerr,
275
                                            initial_contracts_file,
276
                                            debug_mode,
277
                                            timeout,
278
                                            resume,
279
                                            need_full_debug_info,
280
                                            breakpoints
281
                                        );
282

283
    auto start_of_interpret = std::chrono::high_resolution_clock::now();
284

285
    int ret = mm.execute(file_name, preload_module_names) ? 0 : 1;
286

287
    if (ret == 0) {
288
        if (need_time_intervals) {
289
            auto elapsed = std::chrono::duration<float>(std::chrono::high_resolution_clock::now() - start_of_interpret);
290

291
            std::cout << "Интерпретация выполнена за " << elapsed.count() << " с" << std::endl;
292
        }
293
        else if (!need_silence)
294
            std::cout << "Интерпретация выполнена успешно" << std::endl;
295
    }
296
    else if (!need_silence)
297
        std::cout << "Интерпретация прервана" << std::endl;
298

299
    return ret;
300
}
301

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

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

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

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