I'm working on a test project that will ideally be built into a larger project (wanting to build my own scripting language for fun) in the future that parses expressions into a tree structure using my custom classes.
My expected result is an Expression
that can be evaluated but the actual result is an expression that has a null AbstractExpression
pointer.
Expression Classes
Note: State
is a struct that I plan to use to hold variables and other information needed to evaluate
class AbstractExpression
{
public:
AbstractExpression()
{
}
virtual double const Evaluate(State &state) = 0;
virtual ~AbstractExpression() {}
};
class BinaryExpression : public AbstractExpression
{
public:
typedef double(*OperatorFunction)(double, double);
BinaryExpression(char op, AbstractExpression *leftOperand, AbstractExpression *rightOperand)
{
this->left = leftOperand;
this->right = rightOperand;
this->operatorFunction = GetFunction(std::string(1, op));
}
BinaryExpression(std::string op, AbstractExpression *leftOperand, AbstractExpression *rightOperand)
{
this->left = leftOperand;
this->right = rightOperand;
this->operatorFunction = GetFunction(op);
}
~BinaryExpression()
{
delete this->left;
delete this->right;
}
double const Evaluate(State &state)
{
return this->operatorFunction(this->left->Evaluate(state), this->right->Evaluate(state));
}
private:
AbstractExpression *left;
AbstractExpression *right;
OperatorFunction operatorFunction;
static double Add(double left, double right) { return left + right; }
//<... A bunch of definitions like the above ...>
static double NoOp(double left, double right) { return 0; }
static BinaryExpression::OperatorFunction GetFunction(std::string op)
{
if (op.compare("+") == 0)
{
return &Add;
}
//<... Lost of else if statements ...>
else
{
return &NoOp;
}
}
};
class ConstantExpression : public AbstractExpression
{
public:
ConstantExpression(double value)
{
this->value = value;
}
ConstantExpression()
{
this->value = 0;
}
double const Evaluate(State &state)
{
return this->value;
}
private:
double value;
};
class Expression : public AbstractExpression
{
private:
AbstractExpression *expression;
public:
Expression()
{
}
Expression(AbstractExpression *expression)
{
this->expression = expression;
}
~Expression()
{
//delete this->expression;
}
double const Evaluate(State &state)
{
return this->expression->Evaluate(state);
}
};
Parser
namespace Test
{
template <typename Iterator>
struct StatementGrammar : qi::grammar < Iterator, Expression(), ascii::space_type >
{
StatementGrammar() : StatementGrammar::base_type(expression)
{
expression =
constant[qi::_val = phoenix::construct<Expression>(qi::_1)]
;
constant =
qi::double_[qi::_val = &(phoenix::construct<ConstantExpression>(qi::_1))]
;
}
qi::rule < Iterator, Expression(), ascii::space_type > expression;
//qi::rule < Iterator, BinaryExpression*(), ascii::space_type> binaryExpression;
qi::rule < Iterator, ConstantExpression*(), ascii::space_type> constant;
};
}
Below is the code that I'm using to call the parser:
std::string string;
Expression exp;
std::getline(std::cin, string);
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
Test::StatementGrammar<iterator_type> grammar;
std::string::const_iterator iter = string.begin();
std::string::const_iterator end = string.end();
bool result = qi::phrase_parse(iter, end, grammar, space, epx);
if (result)
{
State s;
double foo = exp.Evaluate(s);
}
else
{
std::cout << "No Match!" << std::endl;
}
return 0;
I'm mostly a C# developer (read: I'm a C++/Boost noob) please correct me on everything I'm doing wrong in C++ (I need to learn where my mistakes are!).