diff --git a/Src/Server/Abstract.hpp b/Src/Server/Abstract.hpp index 9c5793f..9f6de8c 100644 --- a/Src/Server/Abstract.hpp +++ b/Src/Server/Abstract.hpp @@ -1,6 +1,9 @@ #pragma once +#include "TOSLib.hpp" +#include #include +#include #include #include #include @@ -169,7 +172,87 @@ struct StateExpression { StateExpression(std::vector, const std::string& expression) { // Скомпилировать выражение и просчитать таблицу CT - + + struct Value { + bool IsMetaData; + union { + int Val; + struct { + uint8_t MetaId, MetaValue; + }; + }; + }; + + struct Node { + std::variant Val1, Val2; + char Func; + }; + + std::vector nodes; + + std::function lambda = [&](const std::string_view& exp) -> Node { + std::vector> tokens; + + // Парсим токены и выражения в круглых скобках + for(size_t pos = 0; pos < exp.size(); pos++) { + if( + (exp[pos] >= 'a' && exp[pos] <= 'z') + || (exp[pos] >= 'A' && exp[pos] <= 'Z') + || (exp[pos] >= '0' && exp[pos] <= '9') + ) { + if(tokens.empty() || tokens.back().index() != 0) { + tokens.push_back(exp[pos]); + } + + std::string& token = std::get<0>(tokens.back()); + token += exp[pos]; + } else if(exp[pos] == '(') { + int depth = 0; + for(size_t pos2 = pos; pos2 < exp.size(); pos2++) { + if(exp[pos2] == '(') + depth++; + else if(exp[pos2] == ')') + depth--; + + if(depth == 0) { + tokens.push_back(lambda(exp.substr(pos+1, pos2-pos-1))); + break; + } + } + + if(depth != 0) { + MAKE_ERROR("Неожиданное завершение выражения"); + } + } else { + tokens.push_back(exp[pos]); + } + } + + while(true) { + for(ssize_t pos = tokens.size()-1; pos >= 0; pos--) { + auto& token = tokens[pos]; + if(token.index() != 1 || std::get<1>(token) != '!' || (pos < tokens.size()-1 && tokens[pos+1].index() == 1)) + continue; + + if(pos == tokens.size()-1) { + MAKE_ERROR("Отсутствует операнд"); + } + + auto& rightToken = tokens[pos+1]; + if(rightToken.index() == 2) { + nodes.push_back(std::get<2>(rightToken)); + uint16_t index = nodes.size()-1; + Node newNode; + newNode.Func = '!'; + newNode.Val2 = index; + } + } + } + }; + + const std::string exp = TOS::Str::replace(expression, " ", ""); + // exp = TOS::Str::replace(expression, "\0", ""); + lambda(exp); for(int meta = 0; meta < 256; meta++) { CT[meta] = true;