loom

Форк
0
/
tokenizer-substitutions.cpp 
204 строки · 7.0 Кб
1
/*
2
MIT License
3

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

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

9
#include "simodo/variable/Module_interface.h"
10
#include "simodo/variable/VariableSetWrapper.h"
11
#include "simodo/inout/convert/functions.h"
12
#include "simodo/variable/json/Serialization.h"
13

14
#include <memory>
15
#include <filesystem>
16
#include <cassert>
17
#include <algorithm>
18

19
#ifdef CROSS_WIN
20
// MinGW related workaround
21
#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
22
#endif
23

24
#include <boost/dll/alias.hpp>
25

26
using namespace simodo;
27
using namespace simodo::variable;
28
using namespace simodo::inout;
29

30
namespace fs = std::filesystem;
31

32
namespace
33
{
34
    Value setup(Module_interface * host, const VariableSetWrapper & args);
35
    Value symbols(Module_interface * host, const VariableSetWrapper & args);
36
    Value produceTokens(Module_interface * host, const VariableSetWrapper & args);
37
}
38

39
class MainTokenizer : public Module_interface
40
{
41
    // ModuleFactory_interface * _factory;
42
    Value                     _substitutions_value;
43

44
public:
45
    // MainTokenizer(ModuleFactory_interface * factory) : _factory(factory) {}
46

47
    Value setup(const std::string & path_to_data, const std::string & language);
48
    Value symbols();
49
    Value produceTokens(const std::u16string & text_to_parse, int position, context_index_t context);
50

51
    virtual version_t version() const override { return lib_version(); }
52

53
    virtual Object instantiate(std::shared_ptr<variable::Module_interface> module_object) override
54
    {
55
        return Object {{
56
            // {u"version", u"0.1"},
57
            {u"specialization", u"Word"},
58
            {u"setup", {ValueType::Function, Object {{
59
                {u"@", ExternalFunction {module_object, ::setup}},
60
                {{}, ValueType::String},
61
                {u"path_to_data", ValueType::String},
62
                {u"language", ValueType::String},
63
            }}}},
64
            {u"symbols", {ValueType::Function, Object {{
65
                {u"@", ExternalFunction {module_object, ::symbols}},
66
                {{}, ValueType::Array},
67
            }}}},
68
            {u"produceTokens", {ValueType::Function, Object {{
69
                {u"@", ExternalFunction {module_object, ::produceTokens}},
70
                {{}, ValueType::Object},
71
                {u"text_to_parse", ValueType::String},
72
                {u"position", ValueType::Int},
73
                {u"context", ValueType::Int},
74
            }}}},
75
        }};
76
    }
77

78
    // virtual ModuleFactory_interface * factory() override { return _factory; }
79

80
    // Factory method
81
    static std::shared_ptr<Module_interface> create() {
82
        return std::make_shared<MainTokenizer>();
83
    }
84
};
85

86
BOOST_DLL_ALIAS(
87
    MainTokenizer::create,    // <-- this function is exported with...
88
    create_simodo_module      // <-- ...this alias name
89
)
90

91
namespace
92
{
93
    Value setup(Module_interface * host, const VariableSetWrapper & args)
94
    {
95
        // Эти условия должны проверяться в вызывающем коде и при необходимости выполняться преобразования
96
        assert(host != nullptr);
97
        assert(args.size() == 2);
98
        assert(args[0].value().type() == ValueType::String);
99
        assert(args[1].value().type() == ValueType::String);
100

101
        MainTokenizer * main = static_cast<MainTokenizer *>(host);
102
        return main->setup(toU8(args[0].value().getString()),
103
                           toU8(args[1].value().getString()));
104
    }
105

106
    Value symbols(Module_interface * host, const VariableSetWrapper & )
107
    {
108
        // Эти условия должны проверяться в вызывающем коде и при необходимости выполняться преобразования
109
        assert(host != nullptr);
110

111
        MainTokenizer * main = static_cast<MainTokenizer *>(host);
112
        return main->symbols();
113
    }
114

115
    Value produceTokens(Module_interface * host, const VariableSetWrapper & args)
116
    {
117
        // Эти условия должны проверяться в вызывающем коде и при необходимости выполняться преобразования
118
        assert(host != nullptr);
119
        assert(args.size() == 3);
120
        assert(args[0].value().type() == ValueType::String);
121
        assert(args[1].value().type() == ValueType::Int);
122
        assert(args[2].value().type() == ValueType::Int);
123

124
        MainTokenizer *        main = static_cast<MainTokenizer *>(host);
125
        context_index_t context = NO_TOKEN_CONTEXT_INDEX;
126
        if (args[2].value().getInt() >= 0 )
127
            context = static_cast<context_index_t>(args[2].value().getInt());
128

129
        return main->produceTokens(args[0].value().getString(), args[1].value().getInt(), context);
130
    }
131

132
}
133

134
Value MainTokenizer::setup(const std::string & path_to_data, const std::string & language)
135
{
136
    fs::path path_to_substitutions = path_to_data;
137
    path_to_substitutions /= "substitutions/" + language + ".json";
138

139
    if (!fs::exists(path_to_substitutions))
140
        return {};
141

142
    loadJson(path_to_substitutions.string(), _substitutions_value);
143
    if (_substitutions_value.type() == ValueType::Object)
144
        return u"";
145

146
    return {}; // Не ОК
147
}
148

149
Value MainTokenizer::symbols()
150
{
151
    if (_substitutions_value.type() != ValueType::Object)
152
        return {};
153

154
    std::vector<variable::Value> result; 
155

156
    const std::shared_ptr<Object> substitutions = _substitutions_value.getObject();
157
    for(const Variable & sub : substitutions->variables()) {
158
        if (sub.type() != ValueType::Array)
159
            continue;
160
        const std::shared_ptr<Array> array = sub.value().getArray();
161
        for(const variable::Value & v : array->values()) {
162
            if (v.type() != variable::ValueType::String)
163
                continue;
164
            Object symbol_data {{
165
                {u"symbol",   v.getString()},
166
                {u"type",     sub.name()},
167
                }};
168
            result.push_back(symbol_data);
169
        }
170
    }
171

172
    return result;
173
}
174

175
Value MainTokenizer::produceTokens(const std::u16string & text_to_parse, int position, context_index_t )
176
{
177
    if (_substitutions_value.type() != ValueType::Object)
178
        return {};
179

180
    Array  tokens;
181
    const std::shared_ptr<Object> substitutions = _substitutions_value.getObject();
182
    for(const Variable & sub : substitutions->variables()) {
183
        if (sub.type() != ValueType::Array)
184
            continue;
185
        const std::shared_ptr<Array> array = sub.value().getArray();
186
        auto it = std::find_if(array->values().begin(), array->values().end(), 
187
                               [text_to_parse](const Value & x) 
188
                {
189
                    return x.type() == ValueType::String && x.getString() == text_to_parse;
190
                });
191
        if (it != array->values().end()) {
192
            tokens.values().push_back(Object {{
193
                {u"token",    text_to_parse},
194
                {u"type",     sub.name()},
195
                {u"position", position},
196
            }});
197
            break;
198
        }
199
    }
200

201
    return Object {{
202
        {u"tokens", tokens},
203
        }};
204
}
205

206

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

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

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

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