解释器模式
1.模式动机与定义
模式动机
- Java语言无法直接解释类似“1+2+3-4+1”这样的字符串
- 定义一套文法规则来实现对这些语句的解释,即设计一个自定义语言
- 基于现有的编程语言 → 面向对象编程语言 → 解释器模式
模式定义
- 解释器模式(Interpreter Pattern):定义一个语言的文法,并且建立一个解释器来解释该语言中的句子
- 此处,“语言”是指使用规定格式和语法的代码√此处,
- 它是一种类行为型模式
2.模式结构与分析
模式结构
解释器模式包含如下角色
- AbstractExpression:抽象表达式:在抽象表达式中声明了抽象的解释操作,它是所有的终结符表达式和非终结符表达式的公共父类
- TerminalExpression: 终结符表达式:抽象表达式的子类,实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例。通常在一个解释器模式中只有少数几个终结符表达式类。它们的实例可以通过非终结符表达式组成较为复杂的句子。
- NonterminalExpression:非终结符表达式:抽象表达式的子类,实现了文法中非终结符的解释操作。由于在非终结符表达式中可以包含终结符表达式,也可以继续包含非终结符表达式。
- Context: 环境类:环境类又称为上下文类,它用于存储解释器之外的一些全局信息。通常它临时存储了需要解释的语句
- Client: 客户类:客户类中构造了表示该文法定义的语言中一个特定句子的抽象语法树,该抽象语法树由非终结符表达式和终结符表达式实例组合而言,在客户类中还将调用解释操作,实现对句子的解释。
模式分析
- 是一种使用频率相对较低但学习难度相对较大的设计模式,用于描述如何使用面向对象语言构成一个简单的语言解释器
- 能够加深对面向对象思想的理解,并且理解编程语言中文法规则的解释过程
文法规则
-
1+2+3-4+1
-
expression ::= value operation operation ::= expression '+'expression | expression '_' expression value ::= an integer //一个整数值 -
“::=”表示“定义为”
-
“|”表示“或”
-
“{”和“}”表示“组合”
-
“*”表示“出现0次或多次”
//终结符表达式类示例代码
public class TerminalExpression extends AbstractExpression {
public void interpret(Context ctx){
//终结符表达式的解释操作
}
}
//非终结符表达式类示例代码
public class NonterminalExpression extends AbstractExpression {
private AbstractExpression left;
private AbstractExpression right;
public NonterminalExpression(AbstractExpressionleft,AbstractExpression right){
this.left=left;
this.right-right;
}
public void interpret(Context ctx){
//递归调用每一个组成部分的interpret()方法
//在递归调用时指定组成部分的连接方式,即非终结符的功能
}
}
环境类Context:
- 用于存储一些全局信息,一般包含一个HashMap或ArrayList等类型的集合对象(也可以直接由HashMap等集合类充当环境类),存储一系列公共信息,例如变量名与值的映射关系(key/value)等,用于在执行具体的解释操作时从中获取相关信息
- 可以在环境类中增加一些所有表达式解释器都共有的功能,以减轻解释器的职责
- 当系统无须提供全局公共信息时可以省略环境类,根据实际情况决定是否需要环境类
public class Context {
private HashMap<String, String> map = new HashMap<String, String>();
public void assign(String key, String value){
//往环境类中设值
map.put(key, value);
}
public String lookup(String key){
//获取存储在环境类中的值
return map.get(key);
}
}
3.模式效果与应用
优点
- 易于改变和扩展文法
- 可以方便地实现一个简单的语言
- 实现文法较为容易(有自动生成工具)
- 增加新的解释表达式较为方便
缺点
- 对于复杂文法难以维护
- 执行效率较低
使用情况
- 可以将一个需要解释执行的语言中的句子表示为一棵抽象语法树
- 一些重复出现的问题可以用一种简单的语言来进行表达
- 一个语言的文法较为简单
- 执行效率不是关键问题
模式应用
- 解释器模式在使用面向对象语言实现的编译器中得到了广泛的应用,如Smalltalk语言的编译器。
- 目前有一些基于Java抽象语法树的源代码处理工具,如在Eclipse中就提供了EclipseAST,它是Eclipse JDT的一个重要组成部分用来表示Java语言的语法结构,用户可以通过扩展其功能,创建自己的文法规则。
- 可以使用解释器模式,通过C++、Java、C#等面向对象语言开发简单的编译器,如数学表达式解析器、正则表达式解析器等,用于增强这些语言的功能使之增加一些新的文法规则,用于解释一些特定类型的语句。
浙公网安备 33010602011771号