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
21
FuzeInterpret_abstract::FuzeInterpret_abstract(Interpret_interface * inter,
22
std::string grammar_name,
23
parser::Grammar & grammar,
24
parser::TableBuildMethod method,
25
bool need_strict_rule_consistency)
27
, _grammar_name(grammar_name)
30
, _need_strict_rule_consistency(need_strict_rule_consistency)
31
, _main_rule(inout::null_token)
35
void FuzeInterpret_abstract::reset()
39
bool FuzeInterpret_abstract::isOperationExists(ast::OperationCode inner_operation_code) const
41
parser::FuzeOperationCode operation_code = static_cast<parser::FuzeOperationCode>(inner_operation_code);
43
switch(operation_code)
45
case parser::FuzeOperationCode::None:
46
case parser::FuzeOperationCode::Main:
47
case parser::FuzeOperationCode::GlobalScript:
48
case parser::FuzeOperationCode::Production:
49
case parser::FuzeOperationCode::RemoveProduction:
50
case parser::FuzeOperationCode::Reference:
59
InterpretState FuzeInterpret_abstract::performOperation(const ast::Node & op)
61
parser::FuzeOperationCode operation_code = static_cast<parser::FuzeOperationCode>(op.operation());
63
switch(operation_code)
65
case parser::FuzeOperationCode::None:
66
return InterpretState::Flow;
68
case parser::FuzeOperationCode::Main:
71
case parser::FuzeOperationCode::GlobalScript:
72
return parseGlobalScript(op);
74
case parser::FuzeOperationCode::Production:
75
return parseProduction(op);
77
case parser::FuzeOperationCode::RemoveProduction:
78
return parseProduction(op, ProductionForWhat::Removing);
80
case parser::FuzeOperationCode::Reference:
87
throw bormental::DrBormental("FuzeInterpret_abstract::performOperation",
88
"Invalid operation index " + std::to_string(static_cast<size_t>(op.operation())));
91
InterpretState FuzeInterpret_abstract::before_finish(InterpretState state)
93
return executeFinal(state);
96
InterpretState FuzeInterpret_abstract::parseMain(const ast::Node & op)
98
return executeMain(op.token());
101
InterpretState FuzeInterpret_abstract::parseGlobalScript(const ast::Node & op)
103
if (op.branches().empty())
104
throw bormental::DrBormental("FuzeInterpret_abstract::parseGlobalScript", "Wrong operation structure");
106
return executeGlobalScript(op.token(), op.branches().front());
109
InterpretState FuzeInterpret_abstract::parseProduction(const ast::Node & op, ProductionForWhat what)
111
std::vector<inout::Token> pattern;
112
inout::Token direction_token = inout::null_token;
115
for(const ast::Node & production_node : op.branches()) {
116
parser::FuzeOperationCode operation_code = static_cast<parser::FuzeOperationCode>(production_node.operation());
118
switch(operation_code) {
119
case parser::FuzeOperationCode::Production_Pattern:
120
for(const ast::Node & pattern_node : production_node.branches()) {
121
// pattern.push_back(pattern_node.operation_symbol());
123
inout::LexemeType type = inout::LexemeType::Empty;
124
const inout::Token & token = pattern_node.token();
126
if (token.type() == inout::LexemeType::Annotation)
127
type = inout::LexemeType::Punctuation;
128
else if (token.type() == inout::LexemeType::Id)
129
type = inout::LexemeType::Compound;
130
else if (token.type() == inout::LexemeType::Punctuation) {
131
if (token.qualification() == inout::TokenQualification::Keyword) {
132
if (token.lexeme() == parser::ANNOTATION_STRING)
133
type = inout::LexemeType::Annotation;
134
else if (token.lexeme() == parser::NUMBER_STRING)
135
type = inout::LexemeType::Number;
136
else if (token.lexeme() == parser::ID_STRING)
137
type = inout::LexemeType::Id;
139
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation structure");
142
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation structure");
145
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation structure");
147
pattern.push_back(inout::Token { {token.lexeme(), type}, token.token(), token.location() });
151
case parser::FuzeOperationCode::Production_Direction:
152
direction_token = production_node.token();
155
case parser::FuzeOperationCode::Production_Script:
156
if (!action.branches().empty() || production_node.branches().empty())
157
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation structure");
158
action = production_node.branches().front();
162
throw bormental::DrBormental("FuzeInterpret_abstract::parseProduction", "Wrong operation code");
166
if (what == ProductionForWhat::Adding)
167
return executeProduction(op.token(), pattern, direction_token, action);
169
return executeRemovingProduction(op.token(), pattern, action);
172
InterpretState FuzeInterpret_abstract::parseRef(const ast::Node & op)
174
if (op.branches().empty())
175
throw bormental::DrBormental("FuzeInterpret_abstract::parseRef", "Wrong operation structure");
177
return executeRef(op.token(), op.branches().front().token().lexeme());
180
InterpretState FuzeInterpret_abstract::executeMain(const inout::Token & main_production)
182
if (_main_rule.lexeme().empty())
183
_main_rule = main_production;
185
return InterpretState::Flow;
188
InterpretState FuzeInterpret_abstract::executeGlobalScript(const inout::Token & label, const ast::Node & script)
190
auto it = _grammar.handlers.find(label.lexeme());
192
if (it != _grammar.handlers.end())
193
ast::NodeFriend::insertBranchBegin( it->second, script.branches() );
195
_grammar.handlers.insert({label.lexeme(), script});
197
return InterpretState::Flow;
200
InterpretState FuzeInterpret_abstract::executeProduction(const inout::Token & production,
201
const std::vector<inout::Token> & pattern,
202
const inout::Token & direction_token,
203
const ast::Node & action)
206
throw AnalyzeException("FuzeInterpret_abstract::executeProduction",
207
production.makeLocation(inter().files()),
208
"The right side of the rule cannot be empty");
210
parser::RuleReduceDirection direction = parser::RuleReduceDirection::Undefined;
212
if (direction_token.type() != inout::LexemeType::Empty)
213
direction = (direction_token.lexeme() == u"<")
214
? parser::RuleReduceDirection::LeftAssociative
215
: parser::RuleReduceDirection::RightAssociative;
217
_rules.push_back({production, pattern, action, direction});
219
return InterpretState::Flow;
222
InterpretState FuzeInterpret_abstract::executeRemovingProduction(const inout::Token & production,
223
const std::vector<inout::Token> & pattern,
224
const ast::Node & action)
227
throw AnalyzeException("FuzeInterpret_abstract::executeRemoveProduction",
228
production.makeLocation(inter().files()),
229
"The right side of the rule cannot be empty");
231
if (!action.branches().empty())
232
throw AnalyzeException("FuzeInterpret_abstract::executeRemoveProduction",
233
production.makeLocation(inter().files()),
234
"When deleting products, you do not need to specify an action");
236
size_t rule_index = findRule(_rules, production, pattern);
238
if (rule_index < _rules.size())
239
_rules.erase(_rules.begin()+rule_index);
241
throw AnalyzeException("FuzeInterpret_abstract::executeRemoveProduction",
242
production.makeLocation(inter().files()),
243
"The specified rule was not found among the previously defined rules");
245
return InterpretState::Flow;
248
InterpretState FuzeInterpret_abstract::executeRef(const inout::Token & , const std::u16string & )
250
return InterpretState::Flow;
253
InterpretState FuzeInterpret_abstract::executeFinal(InterpretState state)
255
if (state != InterpretState::Flow || _rules.empty())
260
std::unique_ptr<ParsingTableBuilder_abstract> builder;
262
if (_method == parser::TableBuildMethod::SLR)
263
builder = std::make_unique<ParsingTableBuilder_SLR>(
268
_need_strict_rule_consistency);
270
builder = std::make_unique<ParsingTableBuilder_LR1>(
275
_need_strict_rule_consistency);
277
if (!builder->build(_rules, _main_rule))
278
return InterpretState::Complete;
280
return InterpretState::Flow;
283
size_t FuzeInterpret_abstract::findRule(const std::vector<parser::GrammarRuleTokens> & rules, const inout::Token &production, const std::vector<inout::Token> &pattern)
286
for(; i < rules.size(); ++i) {
287
const parser::GrammarRuleTokens & r = rules[i];
289
if (r.production.lexeme() != production.lexeme() || r.pattern.size() != pattern.size()) {
294
for(; j < r.pattern.size(); ++j)
295
if (r.pattern[j].token() != pattern[j].token()) {
299
if (j == r.pattern.size()) {