定义
给定一种语言,定义他的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
本质
分离实现,解释执行。
解释器模式使用解释器对象来表示和处理相应的语法规则,一般一个解释器处理一条语法规则。
只要能用解释器对象把符合语法的表达式表示出来,而且能够抽象成语法树,那都可以用解释器模式来处理。
登场角色
-
AbstractExpression(抽象表达式)
定义了语法树节点的共同接口
-
TerminalExpression(终结表达式)
用来实现语法规则中和终结符相关的操作。
-
NonterminalExpression(非终结符表达式)
用来实现语法规则中非终结符相关的操作
-
Context(文脉、上下文)
包含各个解释器需要的数据伙食公共的功能。
-
Client(请求者)
使用解释器的客户端。
示例代码
/**
* 抽象的算数运算解释器
*/
public abstract class ArithmeticExpression {
public abstract int interpret();
}
/**
* 数字解释器
*/
public class NumExpression extends ArithmeticExpression{
private int num;
public NumExpression(int num) {
this.num = num;
}
@Override
public int interpret() {
return num;
}
}
/**
* 运算符号抽象解释器
*/
public abstract class OperatorExpression extends ArithmeticExpression{
public ArithmeticExpression exp1,exp2;
public OperatorExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {
this.exp1 = exp1;
this.exp2 = exp2;
}
}
/**
* 加法运算抽象解释器
*/
public class AdditionExpression extends OperatorExpression{
public AdditionExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {
super(exp1, exp2);
}
@Override
public int interpret() {
return exp1.interpret() + exp2.interpret();
}
}
public class Calculator {
//申明栈存储并操作所有相关的解释器
private Stack<ArithmeticExpression> mExpStack = new Stack<>();
public Calculator(String expression){
ArithmeticExpression exp1,exp2;
String[] elements = expression.split(" ");
//循环遍历表达式元素数组
for(int i=0;i<elements.length;i++){
switch (elements[i].charAt(0)){
case '+':
///将栈中的解释器弹出作为运算符号左边的解释器
exp1 = mExpStack.pop();
//
exp2 = new NumExpression(Integer.valueOf(elements[++i]));
mExpStack.push(new AdditionExpression(exp1,exp2));
break;
default:
mExpStack.push(new NumExpression(Integer.valueOf(elements[i])));
break;
}
}
}
public int calculate(){
return mExpStack.pop().interpret();
}
}
public class Client {
public static void main(String[] args){
Calculator c = new Calculator("1 + 2 + 3 + 4");
System.out.println(c.calculate());
}
}
运行结果
10
优点
- 易于实现语法。在解释器模式中,一条语法规则用一个解释器对象来解释执行。对于解释器的实现来讲,功能就变得比较简单,只需要考虑这一条语法规则的实现就可以了, 其他的不用管。
- 易于扩展新的语法。
- 正是由于采用一个解释器对象负责一条语法规则的方式,使得扩展新的语法非常容易。扩展了新的语法,只需要创建相应的解释器对象,在创建抽象语法树的时候使用这个新的解释器对象就可以了。
缺点
- 不适合复杂的语法。
网友评论