reg parser for interpretor pattern in C++

S

sunil

Hello,
I am working on a problem where I will have a boolean expression
with
upto four variables: A,B,C,D and connected by basic operator &&,||and
may be XOR and NOT in future AND has higher precedence than OR and ()
(parenthesis) takes utmost precedence... I wrote a sample code that
uses interpretor pattern that uses composition pattern to repeatedly
call the evaluate() function, this works properly, however I need to
construct the expression object properly, I hardcoded this (as shown
in the sample code attached below) but would assume I should some
kind
of parsing technique to generate the proper top level expression
object, I have no background in Computer Science (am an electrical
enginner :)) so would need some help here, how to build this parser,
I
GOGled quite a bit and found some info but nothing simple/straight
forward to understand, any pointers on simple layman tuorials/sample
code for this problem would be highly appreciated:

My other question is: is it an overkill to even think of using the
interpretor pattern for problem I am trying to solve, if its OK, is
it
overkill to try building parser is it enough to hardcode the
generation of expression object...


Thanks,
Sunil


P.S.: My interpretor pattern below doesnt need to pass around the
"context" as the object Variable is already updated externally...
Sample code:
//Variable: smallest thing that can be part of expression.
class Variable {
public:
Variable(bool value,string name):_value(value),_name(name) {
}
bool getValue() {
return _value;
}
void setValue(bool value) {
_value=value;
}
string getName() {
return _name;
}
private:
bool _value;
std::string _name;



};


enum
OperatorType{OPERATOR_NONE,AND_OPERATOR,OR_OPERATOR,NOT_OPERATOR};

//Expression is built using variables and symbols and it can be
recursive i.e.
//an expression can be having expression in itself. It can have 1 or
two
//operands but only one operator
class Expression {
public:
Expression(string exprName,OperatorType
operatorType) :_exprName(exprName),_operator(operatorType) {}
~Expression(){}
string getName() {
return _exprName;
}
virtual bool evaluate()=0;
protected:
string _exprName;
OperatorType _operator;



};


//Various basic expressions allowed: AND,OR
//AND
class AndExpression: public Expression {
public:
AndExpression(Expression* exp1,Expression* exp2,string exprName):
Expression(exprName,AND_OPERATOR),_exp1(exp1),_exp2(exp2) {

}


bool evaluate() {
bool retVal;
cout << "Evaluating variable AND expr: name=" << _exprName <<
endl;
retVal = (_exp1->evaluate() && _exp2->evaluate());
cout << "Result of AND expr:" << _exprName << "is:" <<retVal <<
endl;
return retVal;
}


private:
Expression * _exp1;
Expression * _exp2;



};


//OR
class ORExpression: public Expression {
public:
ORExpression(Expression* exp1,Expression *exp2,string exprName):
Expression(exprName,OR_OPERATOR),_exp1(exp1),_exp2(exp2) {

}


bool evaluate() {
bool retVal,exp1Val;
cout << "Evaluating variable OR expr: name=" << _exprName <<
endl;
retVal=(_exp1->evaluate() || _exp2->evaluate());
cout << "Result of OR expr:" << _exprName << " is:" << retVal <<
endl;
return retVal;
}


private:
Expression* _exp1;
Expression* _exp2;



};


//NOT
class NOTExpression: public Expression {
public:

NOTExpression(Expression* exp,string exprName):
Expression(exprName,NOT_OPERATOR),_exp(exp) {
}


bool evaluate() {
bool retVal;
cout << "Evaluating variable NOT expr: name=" << _exprName <<
endl;
retVal = !(_exp->evaluate());
cout << "Result of NOT expr:" << _exprName << " is " << retVal;
return retVal;
}


private:
Expression* _exp;



};


//VariableExpression: expression with variable.
class VariableExpression: public Expression {
public:
VariableExpression(Variable* var): Expression(var->getName()
+"expr",OPERATOR_NONE),_var(var) {
}
bool evaluate() {
cout << "Evaluating variable expr: name=" << _exprName
<< "value= "
<< _var->getValue() <<endl;
return _var->getValue();
}
private:
Variable* _var;


};


int main() {
Variable var1(false,"var1");
Variable var2(true,"var2");
Variable var3(true,"var3");
VariableExpression varExp1(&var1);
VariableExpression varExp2(&var2);
VariableExpression varExp3(&var3);
//(varExp1 || varExp2) && varExp3
Expression *exp = new AndExpression(new
ORExpression(&varExp1,&varExp2,"inexp"),&varExp3,"outexp");
cout << "Result of evaluation=" << exp->evaluate() << endl;
var2.setValue(false);
cout << "Result of evaluation=" << exp->evaluate() << endl;
//Advantage of this approach A||B&C factored in when expression
created.
 
F

Fei Liu

sunil said:
Hello,
I am working on a problem where I will have a boolean expression
with
upto four variables: A,B,C,D and connected by basic operator &&,||and
may be XOR and NOT in future AND has higher precedence than OR and ()
(parenthesis) takes utmost precedence... I wrote a sample code that
uses interpretor pattern that uses composition pattern to repeatedly
call the evaluate() function, this works properly, however I need to
construct the expression object properly, I hardcoded this (as shown
in the sample code attached below) but would assume I should some
kind
of parsing technique to generate the proper top level expression
object, I have no background in Computer Science (am an electrical
enginner :)) so would need some help here, how to build this parser,
I
GOGled quite a bit and found some info but nothing simple/straight
forward to understand, any pointers on simple layman tuorials/sample
code for this problem would be highly appreciated:

My other question is: is it an overkill to even think of using the
interpretor pattern for problem I am trying to solve, if its OK, is
it
overkill to try building parser is it enough to hardcode the
generation of expression object...


Thanks,
Sunil

Hello Sunil, the technique you are looking for is called 'expression
template' in C++, a form of template metaprogramming. The basic concept
is very simple, but of course you will need to work out the details. If
you requirement is more than parsing simple expression, then you should
also take a look at boost::spirit to build embedded parser in C++.

Fei
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top