意图:
给定一个语言,定义它的文法的一种表示,并定义一个解释器模式,这个解释器使用该表示来解释语言中的句子。
适用性:
当一个语言需要解释执行,并且可将语言中的句子表示为一个抽象语法树时,可使用解释器模式。
效果:
1易于改变和扩展文法 该模式使用类来表示文法规则,可使用继承来改变或扩展文法
2易于实现文法 定义抽象语法树中各个节点的类大体类似,这些类易于直接编写
3 复杂的文法难以维护
4增加了新的解释表达式的方法
实现:
1创建抽象语法树 抽象语法树可用一个表驱动的语法分析程序来生成,也可由手写,或直接由Client提供
2定义解释操作 不一定在表达式中定义解释操作,若要经常创建一种新的解释器,那么使用Visitor模式将解释放入一个独立的访问者对象
3与Flyweight模式共享终结符 在一些文法中,一个句子可能多次出现同一个终结符。此时最好共享那个符号的单个拷贝。
Interpreter.h
Interpreter.cpp
- class Context;
- class VariableExp;
- #define MAX_NUM 30
- class BooleanExp
- {
- public:
- BooleanExp();
- virtual ~BooleanExp();
- virtual bool Evaluate(Context&) = 0;
- virtual BooleanExp* Replace(const char*,BooleanExp&) = 0;
- virtual BooleanExp* Copy() const = 0;
- };
- class Context
- {
- public:
- Context();
- ~Context();
- bool Lookup(const char*) const;
- void Assign(VariableExp* x,bool y);
- private:
- char* _name[MAX_NUM];
- bool _value[MAX_NUM];
- };
- class VariableExp : public BooleanExp
- {
- public:
- VariableExp(const char*);
- virtual ~VariableExp();
- virtual bool Evaluate(Context&);
- virtual BooleanExp* Replace(const char*,BooleanExp&);
- virtual BooleanExp* Copy() const;
- char* getname() const {return _name;}
- private:
- char* _name;
- };
- class AndExp:public BooleanExp
- {
- public:
- AndExp(BooleanExp*,BooleanExp*);
- virtual ~AndExp();
- virtual bool Evaluate(Context&);
- virtual BooleanExp* Replace(const char*,BooleanExp&);
- virtual BooleanExp* Copy() const;
- private:
- BooleanExp* _operand1;
- BooleanExp* _operand2;
- };
- class OrExp: public BooleanExp
- {
- public:
- OrExp(BooleanExp*,BooleanExp*);
- virtual ~OrExp();
- virtual bool Evaluate(Context&);
- virtual BooleanExp* Replace(const char*,BooleanExp&);
- virtual BooleanExp* Copy() const;
- private:
- BooleanExp* _operand1;
- BooleanExp* _operand2;
- };
- #include "Interpreter.h"
- #include <iostream>
- #include <string>
- using namespace std;
- VariableExp::VariableExp(const char* name):BooleanExp()
- {
- cout<<"A variableexp is created"<<endl;
- _name = strdup(name);
- }
- VariableExp::~VariableExp()
- {
- cout<<"A variableexp id destroyed"<<endl;
- }
- bool VariableExp::Evaluate(Context& aContext)
- {
- return aContext.Lookup(_name);
- }
- BooleanExp* VariableExp::Copy() const
- {
- return new VariableExp(_name);
- }
- BooleanExp* VariableExp::Replace(const char* name,BooleanExp& exp)
- {
- if (strcmp(name,_name) == 0)
- {
- return exp.Copy();
- }
- else
- {
- return new VariableExp(_name);
- }
- }
- AndExp::AndExp(BooleanExp* op1,BooleanExp* op2)
- {
- _operand1 = op1;
- _operand2 = op2;
- cout<<"An And Exp is created"<<endl;
- }
- AndExp::~AndExp()
- {
- cout<<"An Or Exp is destroyed"<<endl;
- }
- bool AndExp::Evaluate(Context& aContext)
- {
- return _operand1->Evaluate(aContext)&
- _operand2->Evaluate(aContext);
- }
- BooleanExp* AndExp::Copy() const
- {
- return new AndExp(_operand1->Copy(), _operand2->Copy());
- }
- BooleanExp* AndExp::Replace(const char* name,BooleanExp& exp)
- {
- return new AndExp(_operand1->Replace(name,exp),
- _operand2->Replace(name,exp)
- );
- }
- OrExp::OrExp(BooleanExp* op1,BooleanExp* op2)
- {
- _operand1 = op1;
- _operand2 = op2;
- cout<<"An Or operator is created"<<endl;
- }
- OrExp::~OrExp()
- {
- cout<<"An Or operator is destroyed"<<endl;
- }
- bool OrExp::Evaluate(Context& aContext)
- {
- return (_operand1->Evaluate(aContext))||
- ( _operand2->Evaluate(aContext));
- }
- BooleanExp* OrExp::Copy() const
- {
- return new OrExp(_operand1->Copy(),_operand2->Copy());
- }
- BooleanExp* OrExp::Replace(const char* name,BooleanExp& exp)
- {
- return new OrExp(_operand1->Replace(name,exp),
- _operand2->Replace(name,exp)
- );
- }
- BooleanExp::BooleanExp()
- {
- cout<< "A BooleanExp is created."<<endl;
- }
- BooleanExp::~BooleanExp()
- {
- cout<< "A BooleanExp is destoryed."<<endl;
- }
- Context::Context()
- {
- for(int i=0;i<MAX_NUM;i++)
- {
- _name[i]=0;
- _value[i]= false;
- }
- }
- Context::~Context()
- {
- //delete _name;
- cout<<"A context is destroyed"<<endl;
- }
- bool Context::Lookup(const char* X) const
- {
- for (int i =0 ;i<MAX_NUM;i ++)
- {
- if (strcmp (X,_name[i])==0)
- return _value[i];
- }
- return false;
- }
- void Context::Assign(VariableExp* x,bool z)
- {
- int i;
- for (i =0; i<MAX_NUM&&(_name[i]!=0);i ++)
- {
- if (strcmp (x->getname(),_name[i])==0)
- _value[i] = z;
- }
- if (i<MAX_NUM)
- {
- _name[i]=strdup(x->getname());
- _value[i]=z;
- }
- }
- #include <iostream>
- #include "Interpreter.h"
- using namespace std;
- int main()
- {
- BooleanExp* expression1;
- BooleanExp* expression2;
- Context context;
- VariableExp* x = new VariableExp("X");
- VariableExp* y = new VariableExp("Y");
- expression1 = new AndExp(x,y);
- expression2 = new OrExp(x,y);
- context.Assign(x,false);
- context.Assign(y,true);
- bool result1 = expression1->Evaluate(context);
- bool result2 = expression2->Evaluate(context);
- cout<<"The result1 is " << result1<<endl;
- cout<<"The result2 is " << result2<<endl;
- delete expression1;
- delete expression2;
- delete x;
- delete y;
- // Context* a = new Context;
- //delete a;
- return 0;
- }