4
Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo/loom
9
#include "simodo/interpret/builtins/hosts/fuze/FuzeInterpret_abstract.h"
10
#include "simodo/interpret/builtins/hosts/fuze/ParsingTableBuilder_LR1.h"
11
#include "simodo/interpret/builtins/hosts/fuze/ParsingTableBuilder_SLR.h"
13
#include "simodo/interpret/AnalyzeException.h"
14
#include "simodo/parser/fuze/fuze_keywords.h"
15
#include "simodo/ast/NodeFriend.h"
19
namespace simodo::interpret::builtins
22
FuzeInterpret_abstract::FuzeInterpret_abstract(Interpret_interface * inter,
23
std::string grammar_name,
24
parser::Grammar & grammar,
25
parser::TableBuildMethod method,
26
bool need_strict_rule_consistency)
28
, _grammar_name(grammar_name)
31
, _need_strict_rule_consistency(need_strict_rule_consistency)
32
, _main_rule(inout::null_token)
37
void FuzeInterpret_abstract::reset()
41
bool FuzeInterpret_abstract::isOperationExists(ast::OperationCode inner_operation_code) const
43
parser::FuzeOperationCode operation_code = static_cast<parser::FuzeOperationCode>(inner_operation_code);
45
switch(operation_code)
47
case parser::FuzeOperationCode::None:
48
case parser::FuzeOperationCode::Main:
49
case parser::FuzeOperationCode::GlobalScript:
50
case parser::FuzeOperationCode::Production:
51
case parser::FuzeOperationCode::RemoveProduction:
52
case parser::FuzeOperationCode::Reference:
61
InterpretState FuzeInterpret_abstract::performOperation(const ast::Node & op)
63
parser::FuzeOperationCode operation_code = static_cast<parser::FuzeOperationCode>(op.operation());
65
switch(operation_code)
67
case parser::FuzeOperationCode::None:
68
return InterpretState::Flow;
70
case parser::FuzeOperationCode::Main:
73
case parser::FuzeOperationCode::GlobalScript:
74
return parseGlobalScript(op);
76
case parser::FuzeOperationCode::Production:
77
return parseProduction(op);
79
case parser::FuzeOperationCode::RemoveProduction:
80
return parseProduction(op, ProductionForWhat::Removing);
82
case parser::FuzeOperationCode::Reference:
89
throw bormental::DrBormental("FuzeInterpret_abstract::performOperation",
90
"Invalid operation index " + std::to_string(static_cast<size_t>(op.operation())));
93
InterpretState FuzeInterpret_abstract::before_finish(InterpretState state)
95
return executeFinal(state);
98
InterpretState FuzeInterpret_abstract::parseMain(const ast::Node & op)
100
return executeMain(op.token());
103
InterpretState FuzeInterpret_abstract::parseGlobalScript(const ast::Node & op)
105
if (op.branches().empty())
106
throw bormental::DrBormental("FuzeInterpret_abstract::parseGlobalScript", "Wrong operation structure");
108
return executeGlobalScript(op.token(), op.branches().front());
111
InterpretState FuzeInterpret_abstract::parseProduction(const ast::Node & op, ProductionForWhat what)
113
std::vector<inout::Token> pattern;
114
inout::Token direction_token = inout::null_token;
117
for(const ast::Node & production_node : op.branches()) {
118
parser::FuzeOperationCode operation_code = static_cast<parser::FuzeOperationCode>(production_node.operation());
120
switch(operation_code) {
121
case parser::FuzeOperationCode::Production_Pattern:
122
for(const ast::Node & pattern_node : production_node.branches()) {
123
// pattern.push_back(pattern_node.operation_symbol());
125
inout::LexemeType type = inout::LexemeType::Empty;
126
const inout::Token & token = pattern_node.token();
128
if (token.type() == inout::LexemeType::Annotation)
129
type = inout::LexemeType::Punctuation;
130
else if (token.type() == inout::LexemeType::Id)
131
type = inout::LexemeType::Compound;
132
else if (token.type() == inout::LexemeType::Punctuation) {
133
if (token.qualification() == inout::TokenQualification::Keyword) {
134
if (token.lexeme() == parser::ANNOTATION_STRING)
135
type = inout::LexemeType::Annotation;
136
else if (token.lexeme() == parser::NUMBER_STRING)
137
type = inout::LexemeType::Number;
138
else if (token.lexeme() == parser::ID_STRING)
139
type = inout::LexemeType::Id;
141
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation structure");
144
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation structure");
147
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation structure");
149
pattern.push_back(inout::Token { {token.lexeme(), type}, token.token(), token.location() });
153
case parser::FuzeOperationCode::Production_Direction:
154
direction_token = production_node.token();
157
case parser::FuzeOperationCode::Production_Script:
158
if (!action.branches().empty() || production_node.branches().empty())
159
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation structure");
160
action = production_node.branches().front();
164
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation code");
168
if (what == ProductionForWhat::Adding)
169
return executeProduction(op.token(), pattern, direction_token, action);
171
return executeRemovingProduction(op.token(), pattern, action);
174
InterpretState FuzeInterpret_abstract::parseRef(const ast::Node & op)
176
if (op.branches().empty())
177
throw bormental::DrBormental("FuzeInterpret_abstract::parseRef", "Wrong operation structure");
179
return executeRef(op.token(), op.branches().front().token().lexeme());
182
InterpretState FuzeInterpret_abstract::executeMain(const inout::Token & main_production)
184
if (_main_rule.lexeme().empty())
185
_main_rule = main_production;
187
return InterpretState::Flow;
190
InterpretState FuzeInterpret_abstract::executeGlobalScript(const inout::Token & label, const ast::Node & script)
192
auto it = _grammar.handlers.find(label.lexeme());
194
if (it != _grammar.handlers.end())
195
ast::NodeFriend::insertBranchBegin( it->second, script.branches() );
197
_grammar.handlers.insert({label.lexeme(), script});
199
return InterpretState::Flow;
202
InterpretState FuzeInterpret_abstract::executeProduction(const inout::Token & production,
203
const std::vector<inout::Token> & pattern,
204
const inout::Token & direction_token,
205
const ast::Node & action)
208
throw AnalyzeException("FuzeInterpret_abstract::executeProduction",
209
production.makeLocation(_interpret->files()),
210
"The right side of the rule cannot be empty");
212
parser::RuleReduceDirection direction = parser::RuleReduceDirection::Undefined;
214
if (direction_token.type() != inout::LexemeType::Empty)
215
direction = (direction_token.lexeme() == u"<")
216
? parser::RuleReduceDirection::LeftAssociative
217
: parser::RuleReduceDirection::RightAssociative;
219
_rules.push_back({production, pattern, action, direction});
221
return InterpretState::Flow;
224
InterpretState FuzeInterpret_abstract::executeRemovingProduction(const inout::Token & production,
225
const std::vector<inout::Token> & pattern,
226
const ast::Node & action)
229
throw AnalyzeException("FuzeInterpret_abstract::executeRemoveProduction",
230
production.makeLocation(_interpret->files()),
231
"The right side of the rule cannot be empty");
233
if (!action.branches().empty())
234
throw AnalyzeException("FuzeInterpret_abstract::executeRemoveProduction",
235
production.makeLocation(_interpret->files()),
236
"When deleting products, you do not need to specify an action");
238
size_t rule_index = findRule(_rules, production, pattern);
240
if (rule_index < _rules.size())
241
_rules.erase(_rules.begin()+rule_index);
243
throw AnalyzeException("FuzeInterpret_abstract::executeRemoveProduction",
244
production.makeLocation(_interpret->files()),
245
"The specified rule was not found among the previously defined rules");
247
return InterpretState::Flow;
250
InterpretState FuzeInterpret_abstract::executeRef(const inout::Token & , const std::u16string & )
252
return InterpretState::Flow;
255
InterpretState FuzeInterpret_abstract::executeFinal(InterpretState state)
257
if (state != InterpretState::Flow || _rules.empty())
262
std::unique_ptr<ParsingTableBuilder_abstract> builder;
264
if (_method == parser::TableBuildMethod::SLR)
265
builder = std::make_unique<ParsingTableBuilder_SLR>(
267
_interpret->reporter(),
270
_need_strict_rule_consistency);
272
builder = std::make_unique<ParsingTableBuilder_LR1>(
274
_interpret->reporter(),
277
_need_strict_rule_consistency);
279
if (!builder->build(_rules, _main_rule))
280
return InterpretState::Complete;
282
return InterpretState::Flow;
285
size_t FuzeInterpret_abstract::findRule(const std::vector<parser::GrammarRuleTokens> & rules, const inout::Token &production, const std::vector<inout::Token> &pattern)
288
for(; i < rules.size(); ++i) {
289
const parser::GrammarRuleTokens & r = rules[i];
291
if (r.production.lexeme() != production.lexeme() || r.pattern.size() != pattern.size()) {
296
for(; j < r.pattern.size(); ++j)
297
if (r.pattern[j].token() != pattern[j].token()) {
301
if (j == r.pattern.size()) {