【转】设计模式学习笔记(15)-解释器
所谓解释器(Interpreter)就是将一系列指令转化成代码,能够执行的代码。Interpreter本来就有翻译的意思。GoF给它的定义是:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。这很像命令模式,但是命令模式的命令必须是实现了Command的类的实例,而解释器模式的命令则可以是任何对象,如字符串,整数等,只要解释器能将其解释成具体行为就行。
第一个能想到的利用解释器模式的程序应该就是编译器了,编译器能将源代码翻译成机器能认识的机器码,这是很典型的解释器模式。另外正则表达式(RegExp)也是解释器模式的一个应用。其它的领域使用解释器模式是极少的,使用极其有限,另外有了yacc和lex等语法分析工具后使用解释器模式的地方就更少了。
Context存储的全局上下文环境,AbstractExpression是所有表达式必须继承的接口,TerminalExpression和NonterminalExpression是两个实现。
我们举个例子将一个整数字符串小写转大写,然后在首尾添加大括号。
简单的代码如下:
Context类只存储了一个字符串:
|
1
2
3
4
5
6
7
8
9
10
|
class Context {private: string _message;public: Context(string s) : _message(s){} string& getMsg() { return _message; }}; |
定义抽象的表达式类:
|
1
2
3
4
5
|
class AbstractExpression {public: virtual void interpret(Context){};}; |
定义两个解释器,分别是转换为大写和删除
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class UpExpression : public AbstractExpression {public: void interpret(Context& context) { string* s = &context.getMsg(); for(int i = 0; i < s->size(); i++) { s->at(i) = toupper(s->at(i)); } }};class AddExpression : public AbstractExpression {public: void interpret(Context& context) { string* s = &context.getMsg(); s->insert(0, "{"); s->append("}"); }}; |
主方法里这样写:
|
1
2
3
4
|
Context context("abcDeFGhi");(new UpExpression())->interpret(context);(new AddExpression())->interpret(context);cout << context.getMsg() << endl; |
最终输出为:
|
1
|
{ABCDEFGHI} |
当然这个程序没有任何实际的意义,但却基本满足了解释器模式的整体构造。如果我们将写一个表达式运算的程序呢?可以先写一个将中缀表达式转为后缀表达式的解释器,然后写一个运算后缀表达式的计算程序,这和上面的理念是一致的。
GoF的书中说得很多,包括建立语法分析树,定义解释操作等,其实就是上面的例子所说的:先翻译,再执行。
最后来看看解释器模式的适用性:
当有一个语言需要解释执行,并且你可将该语言中的一个句子表示为一个抽象语法树时,可使用解释器模式
总而言之,解释器模式实际用得并不多,了解即可。
转自:http://lecoding.com/articles/236.html
posted on 2013-03-05 16:19 TheKingOfKingFish 阅读(147) 评论(0) 收藏 举报

浙公网安备 33010602011771号