解释器模式 详解
定义
给定一种语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子;
行为型模式
角色
- 上下文环境(Context):一般用来存放文法中各个终结符所对应的具体值;
- 抽象表达式(Expression):声明一个所有的具体表达式角色都需要实现的抽象接口,这个接口主要是interpret方法,称作解释操作;
- 终结符表达式(Terminal Expression): 实现了抽象表达式角色所要求的接口,文法中的每一个终结符都有具体终结表达式与之对应;
- 非终结符表达式(Terminal Expression):文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字;
从网上找到的例图
适用场景
- 当有一个语言需要解释执行,你可将语言中的句子表示为抽象语法树,可以使用解释器模式;
- 该层次结构变得庞大而且难以管理,此时语法分析程序生成器这样的工具是最好的选择,它们无需构建抽象语法树即可解释表达式;
例子
实现代码
/**
* Created by George on 16/7/12.
*/
// 抽象表达式
var Expression = function () {
// 以环境为主,本方法解释给定的任何一个表达式
this.interpret = function (context) {
};
};
// 具体表达式
var Variable = function (value) {
this.value = value;
};
Variable.prototype = new Expression();
Variable.prototype.interpret = function (context) {
return context.lookup(this);
};
// 具体表达式
var Add = function (variable1, variable2) {
this.variable1 = variable1;
this.variable2 = variable2;
};
Add.prototype = new Expression();
Add.prototype.interpret = function (context) {
return this.variable1.interpret(context) + this.variable2.interpret(context);
};
// 环境类定义出从变量到布尔值的一个映射
var Context = function () {
this.map = new Array(2);
};
Context.prototype.assign = function (variable, value) {
this.map[variable.value] = value;
};
Context.prototype.lookup = function (variable) {
var value = this.map[variable.value];
if (value !== null)
return value;
};
//主函数
var x = new Variable(0);
var y = new Variable(1);
var context = new Context(x, y);
context.assign(x, "x");
context.assign(y, "y");
var result = new Add(x, y);
console.log(result.interpret(context));
实现结果:
为xy
该程序实现了字符串的+表达式,其实就是"x" + "y" = "xy"
优缺点
- 可以将一个需要解释器执行的语言中的句子表示为一个抽象语法树;
- 一些重复出现的问题可以用简单的语言来进行表达;
- 一个语言的文法较为简单;
- 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数;
注意的是
- 对于复杂文法难以维护;