Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define exprtk_enable_debugging
- #include "exprtk.hpp"
- #include <memory>
- #include <unordered_map>
- template<class T>
- struct ScannerDetailsT
- {
- uint64_t Key{};
- T Expression;
- std::string Query;
- std::string UserID;
- };
- typedef double Type;
- typedef exprtk::symbol_table<Type> SymbolTableT;
- typedef exprtk::expression<Type> ExpressionT;
- typedef exprtk::parser<Type> ParserT;
- typedef exprtk::function_compositor<Type> CompositorT;
- typedef exprtk::parser_error::type ErrorT;
- typedef std::unordered_map<std::string, Type> VariableMapT;
- typedef std::vector<ScannerDetailsT < ExpressionT>> ExpressionContainerT;
- typedef double EXPRTKTYPE;
- class MathParser
- {
- public:
- MathParser();
- virtual ~MathParser() = default;
- template<typename Function>
- void AddFunction(std::string name, Function function)
- {
- this->SymbolTable.add_function(name, function);
- }
- void AddVariable(const std::string &name, Type value);
- bool ParseExpression(uint64_t key, const std::string &expression, const std::string &userID);
- Type GetOutput(const ExpressionT &Expression);
- ExpressionContainerT ExpressionContainer;
- protected:
- SymbolTableT SymbolTable;
- ParserT Parser;
- VariableMapT VariableMap;
- int count = {0};
- pthread_mutex_t OrderLock;
- std::vector<EXPRTKTYPE> variable;
- void ParserError(const ParserT &parser, const std::string &expression);
- };
- #include "../include/MathParser.hpp"
- #include <iostream>
- MathParser::MathParser() : OrderLock(PTHREAD_MUTEX_INITIALIZER)
- {
- this->SymbolTable.add_constants();
- if (pthread_mutex_init(&OrderLock, nullptr) != 0)
- {
- printf("Order Mutex lock did not initialized for service\n");
- }
- }
- void MathParser::ParserError(const ParserT &parser, const std::string &expression)
- {
- std::cout << "Error : [" << parser.error() << "] Expression : [" << expression << "]" << std::endl;
- for (std::size_t i = 0; i < parser.error_count(); ++i)
- {
- ErrorT error = parser.get_error(i);
- std::cout << "\tError :[" << i
- << "] Position : [" << error.token.position
- << "] Type : [" << exprtk::parser_error::to_str(error.mode)
- << "] Message : [ " << error.diagnostic
- << "] Expression : [" << expression << "]" << std::endl;
- }
- }
- void MathParser::AddVariable(const std::string &name, Type value)
- {
- VariableMapT::iterator iterator = this->VariableMap.find(name);
- if (iterator == this->VariableMap.end())
- {
- std::pair<VariableMapT::iterator, bool> success = this->VariableMap.insert(VariableMapT::value_type(name, value));
- this->SymbolTable.add_variable(name, success.first->second);
- } else
- {
- this->SymbolTable.get_variable(name)->ref() = value;
- }
- }
- bool MathParser::ParseExpression(uint64_t key, const std::string &expression, const std::string &userID)
- {
- bool return_(false);
- if ((pthread_mutex_lock(&OrderLock) == 0))
- {
- ExpressionT Expression;
- SymbolTableT symbolTable = SymbolTable;
- Expression.register_symbol_table(symbolTable);
- this->variable.push_back(1);
- Expression.get_symbol_table().add_variable("token", this->variable[this->count]);
- if (!Parser.compile(expression, Expression))
- {
- this->ParserError(Parser, expression);
- pthread_mutex_unlock(&OrderLock);
- } else
- {
- ++this->count;
- ScannerDetailsT<ExpressionT> scannerDetails;
- scannerDetails.Key = key;
- scannerDetails.Expression = Expression;
- scannerDetails.Query = expression;
- scannerDetails.UserID = userID;
- this->ExpressionContainer.push_back(scannerDetails);
- return_ = true;
- pthread_mutex_unlock(&OrderLock);
- }
- }
- return return_;
- }
- Type MathParser::GetOutput(const ExpressionT &Expression)
- {
- return Expression.value();
- }
- EXPRTKTYPE Rsi(EXPRTKTYPE time, EXPRTKTYPE token)
- {
- /*just for minimal code purpose*/
- return time * 15 / token;
- }
- EXPRTKTYPE Sum(EXPRTKTYPE first, EXPRTKTYPE second, EXPRTKTYPE token)
- {
- return first + second + token;
- }
- int main(int argc, const char** argv)
- {
- MathParser mathParser;
- mathParser.AddFunction("Sum", Sum);
- mathParser.AddFunction("Rsi", Rsi);
- const std::string expression_1 = "var A1 := Rsi(1 , 2, 5); var output := A1 != 0 and A1 > 10; output";
- const std::string expression_2 = "var A1 := Rsi(1 , 2, 12); var A2 := Sum(A1, 4, 54); output";
- if(mathParser.ParseExpression(1234, expression_1, "user1"))
- {
- printf("Parsing failed %s\n", expression_1);
- }
- if(mathParser.ParseExpression(1234, expression_2, "user2"))
- {
- printf("Parsing failed %s\n", expression_2);
- }
- std::for_each(mathParser.ExpressionContainer.begin(), mathParser.ExpressionContainer.end(), [](ScannerDetailsT<ExpressionT> & scanner)
- {
- printf("output of key %ld, query is %s and output is %s\n", scanner.Key, scanner.Query.c_str(), scanner.Expression.get_value() );
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment