解释器模式(Interpreter)
1.意图
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.
如果一种特定类型的问题发生的频率足够高 , 那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器 , 该解释器通过解释这些句子来解决该问题。
2.特点
Expression:抽象表达式,声明一个所有的具体表达式都需要实现的抽象接口;这个接口主要是一个interpret()方法,称做解释操作。
Terminal Expression:终结符表达式,实现了抽象表达式所要求的接口;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
Nonterminal Expression:非终结符表达式,文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+”就是非终结符,解析“+”的解释器就是一个非终结符表达式。
Context:环境,它的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,给R1赋值100,给R2赋值200,这些信息需要存放到环境中。
Client: 构建(或被给定 ) 表示该文法定义的语言中一个特定的句子的抽象语法树。该抽象语法树由Nonterminal Expression和Terminal Expression 的实例装配而成。调用解释操作。
3.UML类图
4.代码
/**
* 抽象表达式,声明一个所有的具体表达式都需要实现的抽象接口;这个接口主要是一个interpret()方法,称做解释操作
*/
public interface Expression {
//解释操作
Integer interpret();
}
/**
* 终结符表达式,实现了抽象表达式所要求的接口;文法中的每一个终结符都有一个具体终结表达式与之相对应。
* 比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
*/
public class TerminalExpression implements Expression {
private Integer i;
public TerminalExpression(Integer i) {
this.i = i;
}
@Override
public Integer interpret() {
return i;
}
}
/**
* 非终结符表达式,文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,
* 比如公式R=R1+R2中,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。
*/
public abstract class NonterminalExpression implements Expression {
public Expression right;
public Expression left;
public NonterminalExpression(Expression right, Expression left) {
this.right = right;
this.left = left;
}
}
public class AddExpression extends NonterminalExpression {
public AddExpression(Expression right, Expression left) {
super(right, left);
}
@Override
public Integer interpret() {
return left.interpret()+right.interpret();
}
}
public class SubExpression extends NonterminalExpression {
public SubExpression(Expression right, Expression left) {
super(right, left);
}
@Override
public Integer interpret() {
return right.interpret()-left.interpret();
}
}
/**
* 环境,它的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,给R1赋值100,给R2赋值200,这些信息需要存放到环境中。
*/
public class Context {
private Map<String,TerminalExpression> valueMap = new HashMap<String,TerminalExpression>();
public void addValue(String key,Integer val){
valueMap.put(key,new TerminalExpression(val));
}
public Integer getValue(String key){
return valueMap.get(key).interpret();
}
}
/**
* 构建(或被给定 ) 表示该文法定义的语言中一个特定的句子的抽象语法树。该抽象语法树由Nonterminal Expression和Terminal Expression 的实例装配而成。调用解释操作。
*/
public class Client {
//a+b-c
private String expression;
private Context context;
public Client(String expression, Context context) {
this.expression = expression;
this.context = context;
}
/**
* 构建表达式语句 计算结果
* @return
*/
public int calculate(){
char[] chars = expression.toCharArray();
char key = chars[0];
Integer value = context.getValue(String.valueOf(key));
TerminalExpression inner = new TerminalExpression(value);
for (int i=0;i<chars.length;i++){
if(chars[i]=='+'){
inner = new TerminalExpression(new AddExpression(inner,new TerminalExpression(context.getValue(String.valueOf(chars[++i])))).interpret());
}else if(chars[i]=='-'){
inner = new TerminalExpression(new SubExpression(inner,new TerminalExpression(context.getValue(String.valueOf(chars[++i])))).interpret());
}
}
return inner.interpret();
}
}
public class InterpreterTest {
public static void main(String[] args) {
//构建终端表达式集合
Context context = new Context();
context.addValue("a",new Integer(10));
context.addValue("b",new Integer(2));
context.addValue("c",new Integer(3));
Client client = new Client("a+b-c",context);
System.out.println(client.calculate());
}
}