描述:对一个表达式进行解释时,将表达式分为终结符、非终结符、运算环境,这样区分能够把表达式的各个部分独立出来扩展。java
名称解释:ide
场景:写个解释器,解释a+b=3,其中a=1,b=2,c=0,另外扩展一个相反数运算使-a=-1。this
实现:code
抽象一个表达式,负责解释终结符或者非终结符,其定义一个解释方法,计算表达式的值,同时覆盖equals和hashCode方法,方便判断两个表达式是否相同orm
abstract class Expression { String name; Expression(String name) { this.name = name; } abstract int interpret(Context ctx); @Override public boolean equals(Object obj) { if(null == obj) { return false; } if(obj instanceof String && name.equals(obj)) { return true; } return false; } @Override public int hashCode() { return name.hashCode(); } }
定义一个终结符表达式,也就是负责计算变量的值get
class Variable extends Expression { Variable(String name) { super(name); } @Override int interpret(Context ctx) { return ctx.lookup(this); } }
定一个非终结符表达式,其名为加法,负责计算两个终结符的值hash
class AddExpression extends Expression { Expression var1; Expression var2; AddExpression(Expression var1, String name, Expression var2) { super(name); this.var1 = var1; this.var2 = var2; } @Override int interpret(Context ctx) { return var1.interpret(ctx) + var2.interpret(ctx); } }
若是想扩展一种运算,能够直接定义一个非终结符表达式,好比定义一个求相反数的运算it
//一个数的相反数 class OppositeExpression extends Expression { Expression var; OppositeExpression(String name, Expression var) { super(name); this.var = var; } @Override int interpret(Context ctx) { return -var.interpret(ctx); } }
定义一个运算环境,用于给变量赋值io
class Context { Map<Expression, Integer> map = new HashMap<Expression, Integer>(); void assign(Expression var, int value) { map.put(var, value); } int lookup(Expression var) { Object obj = map.get(var); if(null == obj) { // 若是变量未初始化,默认是0 return 0; } return (Integer) obj; } }
客户端调用:form
public static void main(String[] args) { Context ctx = new Context(); Variable a = new Variable("a"); Variable b = new Variable("b"); Variable c = new Variable("c"); // 不初始化,默认为0 ctx.assign(a, 1); ctx.assign(b, 2); System.out.println("a = " + a.interpret(ctx)); System.out.println("b = " + b.interpret(ctx)); System.out.println("c = " + c.interpret(ctx)); // 相反数运算 OppositeExpression opposite = new OppositeExpression("-", a); int rs = opposite.interpret(ctx); String exp = String.format("%s%s = %d", opposite.name, a.name, rs); System.out.println(exp); // 加运算 AddExpression add = new AddExpression(a, "+", b); rs = add.interpret(ctx); exp = String.format("%s %s %s = %d", a.name, add.name, b.name, rs); System.out.println(exp); }
结果:
a = 1 b = 2 c = 0 -a = -1 a + b = 3