一、 引子
解释模式描述了如何构 一个简单的语言解释器,主要应用在 使用面向对象语言开发编译器中;在实际应用中,我们可能很少碰到去构造一个语言的文法的情况。
二、定义与结构
定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。解释器模式是一种类行为型模式。
让我们来看看神秘的解释器模式是由什么来组成的吧。
抽象解释器:声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操作。具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释NonterminalExpression完成。
终结符表达式:实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。终结符一半是文法中的运算单元,比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
非终结符表达式:文法中的每条规则对应于一个非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,+就是非终结符,解析+的解释器就是一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
环境角色:这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。
public interface Expression {
public int interpret(Context context);
}
public class Context {
private int num1;
private int num2;
public Context(int num1,int num2)
{
this.num1 = num1;
this.num2 = num2;
}
public int getNum1()
{
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
}
public class Plus implements Expression{
@Override
public int interpret(Context context) {
return context.getNum1()+context.getNum2();
}
}
public class Minus implements Expression{
@Override
public int interpret(Context context) {
return context.getNum1()-context.getNum2();
}
}
public class Test {
public static void main(String[] args) {
int result = new Minus().interpret((new Context(new Plus().interpret(new Context(9, 2)), 8)));
System.out.println(result);
}
}
结果:3