DesignPatterns_Interpreter

///////////////////////////////////////////////////////////////////////////////////////
// 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;
}
發佈了110 篇原創文章 · 獲贊 2 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章