Last active
July 9, 2018 09:22
-
-
Save BraedonWooding/c0cf35716d40218e0aed3427cb27ada9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef AST_H | |
#define AST_H | |
#include <experimental/optional> | |
#include "../../Utils/utils.h" | |
#include <utility> | |
#include <vector> | |
#include <string> | |
#include "../../Utils/variant.h" | |
// 1 + 2 + (3 * 4) / sin(h)^3e+4 > 5 | |
/* == Grammar == | |
* equation := arithmeticExpression (comparison_op arithmeticExpression)? | |
* arithmeticExpression := multiplyingExpression (('+' | '-') multiplyingExpression)* | |
* multiplyingExpression := powExpression (('*' | '/' | '%') powExpression)* | |
* powExpression := signedAtom (('^') signedAtom)* | |
* signedAtom := sign? (func | atom) | |
* func := variable '(' (arithmeticExpression (',' arithmeticExpression)*)? ')' | |
* atom := literal | |
* | variable | |
* | '(' arithmeticExpression ')' | |
* literal := scientific | |
* | ('true' | 'false') | |
* variable := valid_var_start (valid_var)* | |
* valid_var_start := ('A' - 'z') | '_' | |
* valid_var := valid_var_start | ('0' - '9') | |
* number := ('0' - '9')+ | |
* | '.' ('0' - '9')+ | |
* | ('0' - '9')+ '.' ('0' - '9')+ | |
* scientific := sign? number (('e' | 'E') sign? number)? | |
* sign := ('+' | '-') | |
* comparison_op := ('<' | '=' | '>') | |
*/ | |
enum class Token | |
{ | |
NONE, | |
GT, | |
LT, | |
EQ, | |
PLUS, | |
MINUS, | |
LPAREN, | |
RPAREN, | |
POW, | |
DIVIDE, | |
MODULUS, | |
MULTIPLY, | |
SCIENTIFIC_E, | |
COMMA, | |
DIGIT, | |
LETTER, | |
UNDERSCORE, | |
WHITE_SPACE, | |
OTHER, | |
}; | |
using std::experimental::optional; | |
template<class T> | |
using nodePair = std::vector<std::pair<Token, std::unique_ptr<T>>>; | |
template<class T> | |
using optionalMany = optional<nodePair<T>>; | |
class ArithmeticExpressionNode; | |
class MultiplyingExpressionNode; | |
class PowExpressionNode; | |
class SignedAtomNode; | |
class AtomNode; | |
class FunctionNode; | |
class LiteralNode; | |
class VariableNode; | |
class ArithmeticExpressionNode | |
{ | |
public: | |
std::unique_ptr<MultiplyingExpressionNode> lhs; | |
optionalMany<MultiplyingExpressionNode> rhs; // '+' | '-' | |
ArithmeticExpressionNode(std::unique_ptr<MultiplyingExpressionNode> lhs) : lhs(std::move(lhs)) {} | |
ArithmeticExpressionNode(std::unique_ptr<MultiplyingExpressionNode> lhs, nodePair<MultiplyingExpressionNode> rhs) | |
: lhs(std::move(lhs)), rhs(std::move(rhs)) {} | |
}; | |
class EquationNode | |
{ | |
public: | |
std::unique_ptr<ArithmeticExpressionNode> lhs; | |
optional<std::pair<Token, std::unique_ptr<ArithmeticExpressionNode>>> rhs; // '>', '<', '=' | |
EquationNode(std::unique_ptr<ArithmeticExpressionNode> lhs) : lhs(std::move(lhs)) {} | |
EquationNode(std::unique_ptr<ArithmeticExpressionNode> lhs, optional<std::pair<Token, std::unique_ptr<ArithmeticExpressionNode>>> rhs) | |
: lhs(std::move(lhs)), rhs(std::move(rhs)) {} | |
}; | |
class MultiplyingExpressionNode | |
{ | |
public: | |
std::unique_ptr<PowExpressionNode> lhs; | |
optionalMany<PowExpressionNode> rhs; // '*' | '/' | '%' | |
MultiplyingExpressionNode(std::unique_ptr<PowExpressionNode> lhs) : lhs(std::move(lhs)) {} | |
MultiplyingExpressionNode(std::unique_ptr<PowExpressionNode> lhs, nodePair<PowExpressionNode> rhs) | |
: lhs(std::move(lhs)), rhs(std::move(rhs)) {} | |
}; | |
class PowExpressionNode | |
{ | |
public: | |
std::unique_ptr<SignedAtomNode> lhs; | |
optionalMany<SignedAtomNode> rhs; // '^' | |
PowExpressionNode(std::unique_ptr<SignedAtomNode> lhs) : lhs(std::move(lhs)) {} | |
PowExpressionNode(std::unique_ptr<SignedAtomNode> lhs, nodePair<SignedAtomNode> rhs) | |
: lhs(std::move(lhs)), rhs(std::move(rhs)) {} | |
}; | |
class SignedAtomNode | |
{ | |
typedef mpark::variant<std::unique_ptr<FunctionNode>, std::unique_ptr<AtomNode>> SignedAtomNodeExpr; | |
public: | |
std::experimental::optional<Token> sign; // '+' '-' | |
SignedAtomNodeExpr node; | |
SignedAtomNode(SignedAtomNodeExpr node) : node(std::move(node)) { } | |
SignedAtomNode(SignedAtomNodeExpr node, Token token) : sign(token), node(std::move(node)) { } | |
}; | |
class AtomNode | |
{ | |
typedef mpark::variant<std::unique_ptr<VariableNode>, std::unique_ptr<LiteralNode>, std::unique_ptr<ArithmeticExpressionNode>> AtomNodeExpr; | |
public: | |
AtomNodeExpr expr; // arithmetic is for parenthesis | |
AtomNode(AtomNodeExpr node) : expr(std::move(node)) { } | |
}; | |
class FunctionNode | |
{ | |
public: | |
std::string variable; | |
optional<std::vector<std::unique_ptr<ArithmeticExpressionNode>>> arguments; | |
FunctionNode(std::string variable) : variable(variable) { } | |
FunctionNode(std::string variable, std::vector<std::unique_ptr<ArithmeticExpressionNode>> args) | |
: variable(variable), arguments(std::move(args)) { } | |
}; | |
class LiteralNode | |
{ | |
public: | |
mpark::variant<bool, double> value; | |
LiteralNode(bool value) : value(value) { } | |
LiteralNode(double value) : value(value) { } | |
}; | |
class VariableNode | |
{ | |
public: | |
std::string variableName; | |
VariableNode(std::string variableName) : variableName(variableName) {} | |
}; | |
#endif // AST_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment