///////////////////////////////////////////////////////////////////////////////////////
// Interpreter pattern
// - Given a language, define a represention for its grammar along with an interpreter
// that uses the representation to interpret sentences in the language.
///////////////////////////////////////////////////////////////////////////////////////
#include
#include
using namespace std;
// forward declaraction
class VariableExp;
// Context
// - contains information that's global to the interpreter
class Context
{
public:
bool Lookup(char *name) const;
void Assign(VariableExp *exp, bool b);
private:
map _mapping;
};
// AbstractExpression
// - declares an abstract Interpret operation that is common to all nodes in the
// abstract syntax tree.
class BooleanExp
{
public:
virtual ~BooleanExp() { }
virtual bool Evaluate(Context &c) = 0;
};
// TerminalExpression
// - implements an Interpret operation associated with terminal symbols in the
// grammar.
// - an instance is required for every terminal symbol in a sentence.
class VariableExp : public BooleanExp
{
public:
VariableExp(char *name) : _name(name) { }
virtual bool Evaluate(Context &aContext)
{
return aContext.Lookup(_name);
}
const char *GetName()
{
return _name;
}
private:
char *_name;
};
bool Context::Lookup(char *name) const
{
for (map::const_iterator map_it = _mapping.begin();
map_it != _mapping.end(); ++map_it)
{
if (strcmp(map_it->first->GetName(), name) == 0)
{
return map_it->second;
}
}
}
void Context::Assign(VariableExp *exp, bool b)
{
_mapping.insert(std::pair(exp, b));
}
// NonterminalExpression
// - one such class is required for every rule R::=R1R2...Rn in the grammar.
// - maintains instance variables of type AbstractExpression for each of the
// symbols R1 through Rn.
// - implements an Interpret operation for nonterminal symbols in the grammer.
// Interpret typically calls itself recursively on the variables representing
// R1 through Rn.
class AndExp : public BooleanExp
{
public:
AndExp(BooleanExp *op1, BooleanExp *op2) : _operand1(op1), _operand2(op2) { }
virtual bool Evaluate(Context &aContext)
{
return _operand1->Evaluate(aContext) &&
_operand2->Evaluate(aContext);
}
private:
BooleanExp *_operand1;
BooleanExp *_operand2;
};
class OrExp : public BooleanExp
{
public:
OrExp(BooleanExp *op1, BooleanExp *op2) : _operand1(op1), _operand2(op2) { }
virtual bool Evaluate(Context &aContext)
{
return _operand1->Evaluate(aContext) ||
_operand2->Evaluate(aContext);
}
private:
BooleanExp *_operand1;
BooleanExp *_operand2;
};
class NotExp : public BooleanExp
{
public:
NotExp(BooleanExp *op) : _operand(op) { }
virtual bool Evaluate(Context &aContext)
{
return ~_operand->Evaluate(aContext);
}
private:
BooleanExp *_operand;
};
// Client
// - builds(or is given) an abstract syntax tree representing a particular
// sentence in the language that the grammar defines. The abstract syntax
// tree is assembled from instance fo the NonterminalExpression and
// TerminalExpression classes.
// - invokes the Interpret operation.
int main()
{
// VariableExp represents a named variable.
VariableExp *x = new VariableExp("X");
VariableExp *y = new VariableExp("Y");
// boolean expression (x and y) or (x and (not y))
BooleanExp *expression = new OrExp(
new AndExp(x, y), new AndExp(x, new NotExp(y))
);
Context context;
context.Assign(x, true);
context.Assign(y, false);
bool result = expression->Evaluate(context);
return 0;
}
DesignPatterns_Interpreter
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.