解释器模式![]() 在计算机编程中,解释器模式(英語:interpreter pattern),是一种设计模式[1],它规定了如何求值一个语言中的句子。基本想法是使专门计算机语言的每个符号(终结符与非终结符)都有一个类。这个语言中句子的语法树是合成模式的一个实例,它被用来为客户求值(解释)这个句子[2]:243。 结构![]()
对象图展示了运行时交互:
示例C++下面的例子是基于《设计模式》书中先于C++98的样例代码的C++11实现。 #include <iostream>
#include <map>
#include <cstring>
class Context;
class BooleanExp {
public:
BooleanExp() = default;
virtual ~BooleanExp() = default;
virtual bool evaluate(Context&) = 0;
virtual BooleanExp* replace(const char*, BooleanExp&) = 0;
virtual BooleanExp* copy() const = 0;
};
class VariableExp;
class Context {
public:
Context() :m() {}
bool lookup(const VariableExp* key) { return m.at(key); }
void assign(VariableExp* key, bool value) { m[key] = value; }
private:
std::map<const VariableExp*, bool> m;
};
class VariableExp : public BooleanExp {
public:
VariableExp(const char* name_) :name(nullptr) {
name = strdup(name_);
}
virtual ~VariableExp() = default;
virtual bool evaluate(Context& aContext) {
return aContext.lookup(this);
}
virtual BooleanExp* replace( const char* name_, BooleanExp& exp ) {
if (0 == strcmp(name_, name)) {
return exp.copy();
} else {
return new VariableExp(name);
}
}
virtual BooleanExp* copy() const {
return new VariableExp(name);
}
VariableExp(const VariableExp&) = delete; // rule of three
VariableExp& operator=(const VariableExp&) = delete;
private:
char* name;
};
class AndExp : public BooleanExp {
public:
AndExp(BooleanExp* op1, BooleanExp* op2)
:operand1(nullptr), operand2(nullptr) {
operand1 = op1;
operand2 = op2;
}
virtual ~AndExp() = default;
virtual bool evaluate(Context& aContext) {
return operand1->evaluate(aContext) && operand2->evaluate(aContext);
}
virtual BooleanExp* replace(const char* name_, BooleanExp& exp) {
return new AndExp(
operand1->replace(name_, exp),
operand2->replace(name_, exp)
);
}
virtual BooleanExp* copy() const {
return new AndExp(operand1->copy(), operand2->copy());
}
AndExp(const AndExp&) = delete; // rule of three
AndExp& operator=(const AndExp&) = delete;
private:
BooleanExp* operand1;
BooleanExp* operand2;
};
int main() {
BooleanExp* expression;
Context context;
VariableExp* x = new VariableExp("X");
VariableExp* y = new VariableExp("Y");
expression = new AndExp(x, y);
context.assign(x, false);
context.assign(y, true);
bool result = expression->evaluate(context);
std::cout << result << '\n';
context.assign(x, true);
context.assign(y, true);
result = expression->evaluate(context);
std::cout << result << '\n';
}
程序输出为: 0
1
Python下面是Python的例子: from abc import ABC, abstractmethod
class Context():
def __init__(self):
self.var_dict = {}
def lookup(self, key):
return (self.var_dict[key.name]
if key.name in self.var_dict else None)
def assign(self, key, value):
self.var_dict[key.name] = value
class BooleanExp(ABC):
@abstractmethod
def evaluate(self): pass
@abstractmethod
def replace(self): pass
@abstractmethod
def copy(self): pass
class VariableExp(BooleanExp):
def __init__(self, name):
self.name = name
def __str__(self):
return f"({self.name})"
def evaluate(self, context):
return context.lookup(self)
def replace(self, name, exp):
return (exp.copy() if self.name == name
else type(self)(self.name))
def copy(self):
return type(self)(self.name)
class AndExp(BooleanExp):
def __init__(self, opd1=None, opd2=None):
assert opd2 is not None
self.opd1 = opd1
self.opd2 = opd2
def __str__(self):
return f"({self.opd1} and {self.opd2})"
def evaluate(self, context):
opd1 = self.opd1.evaluate(context)
opd2 = self.opd2.evaluate(context)
return opd1 and opd2
def replace(self, name, exp):
opd1 = self.opd1.replace(name, exp)
opd2 = self.opd2.replace(name, exp)
return type(self)(opd1, opd2)
def copy(self):
opd1 = self.opd1.copy()
opd2 = self.opd2.copy()
return type(self)(opd1, opd2)
def demo():
context = Context()
x = VariableExp("X")
y = VariableExp("Y")
exp = AndExp(x, y)
print(exp)
context.assign(x, False)
context.assign(y, True)
print(exp.evaluate(context))
context.assign(x, True)
context.assign(y, True)
print(exp.evaluate(context))
z = VariableExp("Z")
exp1 = exp.replace("X", z)
print(exp1)
print(exp1.evaluate(context))
context.assign(z, False)
print(exp1.evaluate(context))
其输出: >>> demo()
((X) and (Y))
False
True
((Z) and (Y))
None
False
参见引用
外部链接維基教科書中的相關電子教程:Interpreter |
Index:
pl ar de en es fr it arz nl ja pt ceb sv uk vi war zh ru af ast az bg zh-min-nan bn be ca cs cy da et el eo eu fa gl ko hi hr id he ka la lv lt hu mk ms min no nn ce uz kk ro simple sk sl sr sh fi ta tt th tg azb tr ur zh-yue hy my ace als am an hyw ban bjn map-bms ba be-tarask bcl bpy bar bs br cv nv eml hif fo fy ga gd gu hak ha hsb io ig ilo ia ie os is jv kn ht ku ckb ky mrj lb lij li lmo mai mg ml zh-classical mr xmf mzn cdo mn nap new ne frr oc mhr or as pa pnb ps pms nds crh qu sa sah sco sq scn si sd szl su sw tl shn te bug vec vo wa wuu yi yo diq bat-smg zu lad kbd ang smn ab roa-rup frp arc gn av ay bh bi bo bxr cbk-zam co za dag ary se pdc dv dsb myv ext fur gv gag inh ki glk gan guw xal haw rw kbp pam csb kw km kv koi kg gom ks gcr lo lbe ltg lez nia ln jbo lg mt mi tw mwl mdf mnw nqo fj nah na nds-nl nrm nov om pi pag pap pfl pcd krc kaa ksh rm rue sm sat sc trv stq nso sn cu so srn kab roa-tara tet tpi to chr tum tk tyv udm ug vep fiu-vro vls wo xh zea ty ak bm ch ny ee ff got iu ik kl mad cr pih ami pwn pnt dz rmy rn sg st tn ss ti din chy ts kcg ve