loom

Форк
0
219 строк · 8.9 Кб
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/inout/reporter/ConsoleReporter.h"
17
#include "simodo/inout/convert/functions.h"
18
#include "simodo/LibVersion.h"
19
#include "simodo/inout/token/InputStream.h"
20
#include "simodo/parser/fuze/fuze_file_extension.h"
21
#include "simodo/utility/grammatize.h"
22

23
#include <iostream>
24
#include <fstream>
25
#include <memory>
26
#include <algorithm>
27
#include <chrono>
28

29
#if __cplusplus >= __cpp_2017
30
#include <filesystem>
31
namespace fs = std::filesystem;
32
#else
33
#include <experimental/filesystem>
34
namespace fs = std::filesystem::experimental;
35
#endif
36

37
using namespace std;
38
using namespace simodo;
39
 
40
int main(int argc, char *argv[])
41
{
42
    vector<std::string> arguments(argv + 1, argv + argc);
43

44
    string  json_file_name      = "";
45
    string  st_dot_file_name    = "";
46
    string  dot_file_name       = "";
47
    string  grammar_file        = "";
48
    string  grammar_builder_method_string = "";
49
    bool    need_time_intervals = false;
50
    bool    need_state_transitions_info = false;
51
    bool    need_rules_info     = false;
52
    bool    need_st_info        = false;
53
    bool	error               = false;
54
    bool	help                = false;
55
    bool	version             = false;
56
    bool    need_silence        = false;
57
    bool    need_build_grammar  = false;
58
    bool    need_load_grammar   = false;
59
    bool    need_analyze_inserts= false;
60

61
    for(size_t i=0; i < arguments.size(); ++i)
62
    {
63
        const string & arg = arguments[i];
64

65
        if (arg[0] == '-')
66
        {
67
            if (arg == "--help" || arg == "-h")
68
                help = true;
69
            else if (arg == "--version" || arg == "-v")
70
                version = true;
71
            else if (arg == "--grammar-builder-method" || arg == "-z")
72
            {
73
                if (i == arguments.size()-1 || !grammar_builder_method_string.empty())
74
                    error = true;
75
                else
76
                    grammar_builder_method_string = arguments[++i];
77
            }
78
            else if (arg == "--json-semantics" || arg == "-j")
79
            {
80
                if (i == arguments.size()-1 || !json_file_name.empty())
81
                    error = true;
82
                else
83
                    json_file_name = arguments[++i];
84
            }
85
            else if (arg == "--dot-semantics" || arg == "-s")
86
            {
87
                if (i == arguments.size()-1 || !st_dot_file_name.empty())
88
                    error = true;
89
                else
90
                    st_dot_file_name = arguments[++i];
91
            }
92
            else if (arg == "--dot-grammar" || arg == "-d")
93
            {
94
                if (i == arguments.size()-1 || !st_dot_file_name.empty())
95
                    error = true;
96
                else
97
                    dot_file_name = arguments[++i];
98
            }
99
            else if (arg == "--state-transitions-info" || arg == "-i")
100
                need_state_transitions_info = true;
101
            else if (arg == "--rules-info" || arg == "-r")
102
                need_rules_info = true;
103
            else if (arg == "--insertion-info" || arg == "-o")
104
                need_st_info = true;
105
            else if (arg == "--time-intervals" || arg == "-t")
106
                need_time_intervals = true;
107
            else if (arg == "--silence" || arg == "-S")
108
                need_silence = true;
109
            else if (arg == "--dump-grammar" || arg == "-u")
110
                need_build_grammar = true;
111
            else if (arg == "--load-grammar" || arg == "-l")
112
                need_load_grammar = true;
113
            else if (arg == "--analyze-inserts" || arg == "-a")
114
                need_analyze_inserts = true;
115
            else
116
                error = true;
117
        }
118
        else if (grammar_file.empty())
119
            grammar_file = arg;
120
        else
121
            error = true;
122
    }
123

124
    parser::TableBuildMethod grammar_builder_method = parser::TableBuildMethod::LR1;
125

126
    if (grammar_builder_method_string == "lr" || grammar_builder_method_string == "lr1")
127
        grammar_builder_method = parser::TableBuildMethod::LR1;
128
    else if (grammar_builder_method_string == "slr")
129
        grammar_builder_method = parser::TableBuildMethod::SLR;
130
    else if (!grammar_builder_method_string.empty()) {
131
        cout << "Задан недопустимый метод формирования таблицы грамматики" << endl;
132
        error = true;
133
    }
134

135
    if (grammar_file.empty() && !version && !help)
136
        error = true;
137

138
    if (need_load_grammar && (need_build_grammar || need_time_intervals))
139
        error = true;
140

141
    if (need_load_grammar && (!json_file_name.empty() || !st_dot_file_name.empty())) {
142
        cout << "Нельзя построить JSON или граф семантического дерева из загружаемой грамматики" << endl;
143
        error = true;
144
    }
145

146
    if (error) {
147
        cout << "Ошибка в параметрах запуска" << endl;
148
        help = true;
149
    }
150

151
    const string logo = "Утилита анализа грамматики. Проект SIMODO.";
152

153
    if (help)
154
        cout	<< logo << endl
155
                << "Формат запуска:" << endl
156
                << "    simodo-grammatize [<параметры>] <файл>" << endl
157
                << "Параметры:" << endl
158
                << "    -h | --help                   - отображение подсказки по запуску программы" << endl
159
                << "    -v | --version                - отображение версии программы" << endl
160
                << "    -z | --grammar-builder-method <метод> - метод построения таблицы грамматики (slr,lr1)" << endl
161
                << "    -t | --time-intervals         - отображать интервалы времени разбора" << endl
162
                << "    -j | --json-semantics <путь>  - создать JSON-файл абстрактного дерева операционной семантики" << endl
163
                << "    -s | --dot-semantics <путь>   - создать DOT-файл абстрактного дерева операционной семантики" << endl
164
                << "    -d | --dot-grammar <путь>     - создать DOT-файл графа переходов состояний грамматики" << endl
165
                << "    -r | --rules-info             - вывести перечень правил грамматики" << endl
166
                << "    -i | --state-transitions-info - вывести информацию о переходах состояний грамматики" << endl
167
                << "    -o | --insertion-info         - вывести структуры семантических вставок" << endl
168
                << "    -S | --silence                - не выводить диагностику утилиты" << endl
169
                << "    -u | --dump-grammar           - построить и сохранить грамматику в дампе" << endl
170
                << "    -l | --load-grammar           - загрузить грамматику из дампа" << endl
171
                << "    -a | --analyze-inserts        - анализ вставок кода" << endl
172
                ;
173

174
    if (error)
175
        return 1;
176

177
    if (version)
178
        cout << logo << endl
179
             << "Версия: " << lib_version().major() << "." << lib_version().minor() << endl;
180

181
    if (grammar_file.empty())
182
        return 0;
183

184
    fs::path grammar_path = grammar_file;
185

186
    if (grammar_path.extension().empty())
187
        grammar_path += parser::FUZE_FILE_EXTENSION;
188

189
    std::ifstream in(grammar_path);
190

191
    if (!in) {
192
        cout << "Ошибка при открытии файла '" << grammar_path.string() << "'" << endl;
193
        return 1;
194
    }
195

196
    inout::InputStream      in_stream(in);
197
    inout::ConsoleReporter  m;
198
    parser::Grammar         grammar;
199

200
    return utility::grammatize(
201
                        grammar_file,
202
                        in_stream,
203
                        cout,
204
                        m,
205
                        json_file_name,
206
                        st_dot_file_name,
207
                        grammar_builder_method,
208
                        dot_file_name,
209
                        need_state_transitions_info,
210
                        need_rules_info,
211
                        need_st_info,
212
                        need_time_intervals,
213
                        need_silence,
214
                        need_build_grammar,
215
                        need_load_grammar,
216
                        need_analyze_inserts,
217
                        need_analyze_inserts,
218
                        grammar) ? 0 : 1;
219
}
220

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

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

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

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