Skip to content

Instantly share code, notes, and snippets.

@osa1
Created February 21, 2013 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save osa1/5005037 to your computer and use it in GitHub Desktop.
Save osa1/5005037 to your computer and use it in GitHub Desktop.
#include <string>
#include <sstream>
#include <iostream>
class AddExp;
class MulExp;
class Number;
class ExpVisitor {
public:
virtual void visit(const AddExp * const exp) = 0;
virtual void visit(const MulExp * const exp) = 0;
virtual void visit(const Number * const exp) = 0;
virtual ~ExpVisitor() {};
};
class Exp { // base class for expressions
public:
virtual ~Exp() {}
virtual void accept(ExpVisitor *visitor) const = 0;
};
class AddExp : public Exp {
public:
const Exp * const e1, * const e2;
AddExp(const Exp * const e1, const Exp * const e2)
: e1(e1), e2(e2) {}
void accept(ExpVisitor *visitor) const { visitor->visit(this); }
};
class MulExp : public Exp {
public:
const Exp * const e1, * const e2;
MulExp(const Exp * const e1, const Exp * const e2)
: e1(e1), e2(e2) {}
void accept(ExpVisitor *visitor) const { visitor->visit(this); }
};
class Number : public Exp {
public:
const float f;
Number(const float f) : f(f) {}
void accept(ExpVisitor *visitor) const { visitor->visit(this); }
};
class Run : public ExpVisitor {
public:
float result;
Run() : result(0) {}
void visit(const AddExp * const exp) {
Run v1;
exp->e1->accept(&v1);
Run v2;
exp->e2->accept(&v2);
result = v1.result + v2.result;
}
void visit(const MulExp * const exp) {
Run v1;
exp->e1->accept(&v1);
Run v2;
exp->e2->accept(&v2);
result = v1.result * v2.result;
}
void visit(const Number * const exp) {
result = exp->f;
}
};
class StringOfExp : public ExpVisitor {
public:
std::string result;
StringOfExp() : result(std::string()) {}
void visit(const AddExp * const exp) {
StringOfExp v1;
exp->e1->accept(&v1);
StringOfExp v2;
exp->e2->accept(&v2);
result = "(" + v1.result + " + " + v2.result + ")";
}
void visit(const MulExp * const exp) {
StringOfExp v1;
exp->e1->accept(&v1);
StringOfExp v2;
exp->e2->accept(&v2);
result = "(" + v1.result + " * " + v2.result + ")";
}
void visit(const Number * const exp) {
std::ostringstream ss;
ss << exp->f;
result = ss.str();
}
};
int main () {
Exp *prog1 = new AddExp(
new Number(10), new MulExp(
new Number(20), new AddExp(
new Number(30), new Number(40))));
Run r;
prog1->accept(&r);
std::cout << "return value Run: " << r.result << std::endl;
StringOfExp s;
prog1->accept(&s);
std::cout << "return value of StringOfExp: " << s.result << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment