#pragma once #include #include #include #include namespace Expression { #if 0 namespace TokenType { enum TokenType { VAR, CONST, OPERATOR }; } #endif class Token { public: enum TokenType { VAR, CONST, OPERATOR } t; enum Operator { OPA, // opening parentheses CPA, // closing parentheses ADD, SUB, MUL, DIV, POW }; union TokenValue { std::shared_ptr s; double d; Operator o; explicit TokenValue(std::string& s) : s(std::make_shared(s)) { } explicit TokenValue(double d) : d(d) { } explicit TokenValue(enum Operator o) : o(o) { } explicit TokenValue(void) { } ~TokenValue(void) { } } v; Token(void) { } Token(std::string s) : v(s) { t = VAR; } Token(double d) : v(d) { t = CONST; } Token(enum Operator o) : v(o) { t = OPERATOR; } Token(Expression::Token&& other) { t = other.t; switch (t) { case VAR: v.s = other.v.s; break; case CONST: v.d = other.v.d; break; case OPERATOR: v.o = other.v.o; break; default: std::cout << "Warning: token type is invalid\n"; break; } } std::shared_ptr to_str(void) const { switch (t) { case VAR: return v.s; case CONST: { char buffer[128] = {0}; return std::make_shared((std::ostringstream() << v.d).str()); } case OPERATOR: return std::make_shared("OP " + std::string(op_str())); default: return std::make_shared("Not a valid token!"); } } const char *type_str(void) const { switch (t) { case VAR: return "VAR"; case CONST: return "CONST"; case OPERATOR: return "OPERATOR"; default: return "Not a valid type"; } } const char *op_str(void) const { if (t != OPERATOR) { return "Token is not an operator!"; } switch (v.o) { case OPA: return "OPA"; case CPA: return "CPA"; case ADD: return "ADD"; case SUB: return "SUB"; case MUL: return "MUL"; case DIV: return "DIV"; case POW: return "POW"; default: return "Invalid operator"; } } }; class TreeNode { public: TreeNode *l; // left hand TreeNode *r; // right hand Token o; // operator ~TreeNode() { if (l != nullptr) { delete l; } if (r != nullptr) { delete r; } } }; }