Skip to content

Instantly share code, notes, and snippets.

@thevar1able
Created September 24, 2015 22:34
Show Gist options
  • Save thevar1able/bfa8bf553f6f86d8eee8 to your computer and use it in GitHub Desktop.
Save thevar1able/bfa8bf553f6f86d8eee8 to your computer and use it in GitHub Desktop.
class expression
{
private:
static double OREXPR(std::vector<std::string> exp) {
std::vector<std::string>::iterator op;
if ((op = std::find(exp.begin(), exp.end(), "or")) != exp.end()) {
double first = ANDEXPR(std::vector <std::string>(exp.begin(), op));
double second = OREXPR(std::vector <std::string>(op + 1, exp.end()));
return first || second;
}
return ANDEXPR(exp);
}
static double ANDEXPR(std::vector<std::string> exp) {
std::vector<std::string>::iterator op;
if ((op = std::find(exp.begin(), exp.end(), "and")) != exp.end()) {
double first = COMEXPR(std::vector <std::string>(exp.begin(), op));
double second = ANDEXPR(std::vector <std::string>(op + 1, exp.end()));
return first && second;
}
return COMEXPR(exp);
}
static double COMEXPR(std::vector<std::string> exp) {
std::vector<std::string>::iterator op;
if ((op = std::find_if(exp.begin(), exp.end(), is_comp)) != exp.end()) {
double first = PMEXPR(std::vector <std::string>(exp.begin(), op));
double second = COMEXPR(std::vector <std::string>(op + 1, exp.end()));
if (*op == "<") {
return first < second;
}
else if (*op == ">") {
return first > second;
}
else if (*op == "<=") {
return first <= second;
}
else if (*op == ">=") {
return first >= second;
}
else if (*op == "==") {
return first == second;
}
else if (*op == "~=") {
return first != second;
}
}
return PMEXPR(exp);
}
static double PMEXPR(std::vector<std::string> exp) {
std::vector<std::string>::iterator op;
if ((op = std::find_if(exp.begin(), exp.end(), is_pm)) != exp.end()) {
double first = TERM(std::vector <std::string>(exp.begin(), op));
double second = PMEXPR(std::vector <std::string>(op + 1, exp.end()));
if (*op == "-") {
return first - second;
}
else if (*op == "+") {
return first + second;
}
}
return TERM(exp);
}
static double TERM(std::vector<std::string> exp) {
std::vector<std::string>::iterator op;
if ((op = std::find_if(exp.begin(), exp.end(), is_term)) != exp.end()) {
double first = VAL(std::vector <std::string>(exp.begin(), op));
double second = TERM(std::vector <std::string>(op + 1, exp.end()));
if (*op == "*") {
return first * second;
}
else if (*op == "/") {
return first / second;
}
else if (*op == "%") {
return int(first) % int(second);
}
}
return VAL(exp);
}
static double VAL(std::vector<std::string> exp) {
if (exp.size() == 1) {
if (is_number(exp[0])) return atof(exp[0].c_str());
else if (exp[0] == "true") {
return 1;
}
else if (exp[0] == "false") {
return 0.0;
}
else throw "Wrong expression";
}
else if (exp.size() == 2) {
if (exp[0] == "not" && is_number(exp[1])) {
return 0.0;
}
else if (exp[0] == "not" && exp[1] == "True") {
return 0.0;
}
else if (exp[0] == "not" && exp[1] == "False") {
return 1;
}
else if (exp[0] == "-" && is_number(exp[1])) {
return - atof(exp[1].c_str());
}
else throw "Wrong expression";
}
else OREXPR(std::vector<std::string>(exp.begin() + 1, exp.end() - 1));
}
public:
std::vector<token> expr;
expression(std::vector<token> expr): expr(expr) {}
~expression() {}
virtual void print()
{
for(auto x : expr)
{
std::cout<<"'"<<x.text<<"' ";
}
std::cout<<std::endl;
}
virtual double eval()
{
if(expr.size() == 1)
{
if(atof(expr[0].text.c_str()) != 0.0 || expr[0].text == "0")
{
return atof(expr[0].text.c_str());
}
if(expr[0].type == "ID")
{
return dictionary[expr[0].text];
}
}
else
{
std::vector<std::string> exp;
for(auto x : expr)
{
if(x.type == "ID")
{
exp.push_back(std::to_string(dictionary[x.text]));
}
else
{
exp.push_back(x.text);
}
}
return OREXPR(exp);
}
return 0;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment