4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo/loom
9
/*! \file Интерпретация текста
11
* Утилита интерпретации текста на любом языке, заданном грамматикой на языке SIMODO fuze.
16
#include "simodo/interpret/SemanticModuleFactory_interface.h"
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"
34
#if __cplusplus >= __cpp_2017
36
namespace fs = std::filesystem;
38
#include <experimental/filesystem>
39
namespace fs = std::filesystem::experimental;
42
#include <boost/dll/import.hpp>
44
namespace dll = boost::dll;
46
using namespace simodo;
48
static const std::string DIGITS = "0123456789";
50
int main(int argc, char *argv[])
52
std::vector<std::string> arguments(argv + 1, argv + argc);
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;
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;
69
bool need_full_debug_info= false;
70
std::vector<interpret::BreakPoint> breakpoints;
72
for(size_t i=0; i < arguments.size(); ++i)
74
const std::string & arg = arguments[i];
78
if (arg == "--help" || arg == "-h")
80
else if (arg == "--version" || arg == "-v")
82
else if (arg == "--type" || arg == "-p")
84
if (i == arguments.size()-1 || !type_string.empty())
87
type_string = arguments[++i];
89
else if (arg == "--semantics-dir" || arg == "-s")
91
if (i == arguments.size()-1)
94
interpret_places.push_back(arguments[++i]);
96
else if (arg == "--hard-modules-dir" || arg == "-a")
98
if (i == arguments.size()-1)
101
hard_module_places.push_back(arguments[++i]);
103
else if (arg == "--preload-module" || arg == "-m")
105
if (i == arguments.size()-1)
108
preload_module_names.push_back(arguments[++i]);
110
else if (arg == "--grammars-dir" || arg == "-g")
112
if (i == arguments.size()-1)
115
grammar_places.push_back(arguments[++i]);
117
else if (arg == "--initial-contracts-file" || arg == "-c")
119
if (i == arguments.size()-1)
122
initial_contracts_file = arguments[++i];
124
else if (arg == "--time-intervals" || arg == "-t")
125
need_time_intervals = true;
126
else if (arg == "--silence" || arg == "-S")
128
else if (arg == "--stop") {
131
if (i != arguments.size()-1 && DIGITS.find(arguments[i+1][0]) != std::string::npos) {
133
timeout = std::stoul(arguments[i]);
136
else if (arg == "--debug" || arg == "-d") {
138
if (i != arguments.size()-1 && DIGITS.find(arguments[i+1][0]) != std::string::npos) {
140
timeout = std::stoul(arguments[i]);
143
else if (arg == "--full-debug-info" || arg == "-f") {
144
need_full_debug_info = true;
147
else if (arg == "--breakpoint" || arg == "-b") {
150
if (i == arguments.size()-1)
154
bool line_first = true;
155
for(const auto & c : arguments[i])
156
if (DIGITS.find(c) == std::string::npos) {
161
breakpoints.push_back({file_name, inout::position_line_t(std::stoul(arguments[i]))});
162
else if (i == arguments.size()-1)
165
std::string uri = arguments[i];
168
bool line_second = true;
169
for(const auto & c : arguments[i])
170
if (DIGITS.find(c) == std::string::npos) {
175
breakpoints.push_back({uri, inout::position_line_t(std::stoul(arguments[i]))});
184
else if (file_name.empty())
190
interpret::InterpretType interpret_type = interpret::InterpretType::Preview;
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;
201
if (file_name.empty() && !version && !help)
205
std::cout << "Ошибка в параметрах запуска" << std::endl;
209
const std::string logo = "Утилита интерпретации. Проект SIMODO.";
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
242
std::cout << logo << std::endl
243
<< "Версия: " << lib_version().major() << "." << lib_version().minor() << std::endl;
245
if (file_name.empty())
248
if (interpret_places.empty())
249
interpret_places.push_back("bin/semantics");
251
if (hard_module_places.empty())
252
hard_module_places.push_back("bin/modules");
254
if (grammar_places.empty())
255
grammar_places.push_back("data/grammar");
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();
264
inout::ConsoleReporter r;
265
inout::RegularInputStreamSupplier file_supplier;
266
interpret::SemanticDataCollector_null semantic_data;
267
module::ModuleManagement mm( r,
275
initial_contracts_file,
279
need_full_debug_info,
283
auto start_of_interpret = std::chrono::high_resolution_clock::now();
285
int ret = mm.execute(file_name, preload_module_names) ? 0 : 1;
288
if (need_time_intervals) {
289
auto elapsed = std::chrono::duration<float>(std::chrono::high_resolution_clock::now() - start_of_interpret);
291
std::cout << "Интерпретация выполнена за " << elapsed.count() << " с" << std::endl;
293
else if (!need_silence)
294
std::cout << "Интерпретация выполнена успешно" << std::endl;
296
else if (!need_silence)
297
std::cout << "Интерпретация прервана" << std::endl;