JAVA设计模式之 19.解释器设计模式

it2023-01-21  52

当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性应用场景:编译器、运算表达式计算、正则表达式、机器人等使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低. //解释器设计模式 public class InterpreterPattern { public static void main (String[] args) throws IOException { String expStr = getExpStr(); // a+b HashMap<String, Integer> var = getValue(expStr);// var {a=10, b=20} Calculator calculator = new Calculator(expStr); System.out.println("运算结果:" + expStr + "=" + calculator.run(var)); } // 获得表达式 public static String getExpStr() throws IOException { System.out.print("请输入表达式:"); return (new BufferedReader(new InputStreamReader(System.in))).readLine(); } // 获得值映射 public static HashMap<String, Integer> getValue(String expStr) throws IOException { HashMap<String, Integer> map = new HashMap<>(); for (char ch : expStr.toCharArray()) { if (ch != '+' && ch != '-') { if (!map.containsKey(String.valueOf(ch))) { System.out.print("请输入" + String.valueOf(ch) + "的值:"); String in = (new BufferedReader(new InputStreamReader(System.in))).readLine(); map.put(String.valueOf(ch), Integer.valueOf(in)); } } } return map; } } //抽象类表达式,可以获取到变量的值 abstract class Expression { //HashMap {a=10,b=20} abstract int interpreter(HashMap<String, Integer> var); } class VarExpression extends Expression { private String key; public VarExpression(String key) { this.key = key; } @Override int interpreter(HashMap<String, Integer> var) { return var.get(this.key); } } class SymbolExpression extends Expression { protected Expression left; protected Expression right; public SymbolExpression(Expression left, Expression right) { this.left = left; this.right = right; } //因为SymbolExpression是让其子类来实现的,interpreter是一个默认实现 @Override int interpreter(HashMap<String, Integer> var) { return 0; } } class AddExpression extends SymbolExpression { public AddExpression(Expression left, Expression right) { super(left, right); } //返回left, right 表达式的值将其相加 public int interpreter(HashMap<String, Integer> var) { return super.left.interpreter(var) + super.right.interpreter(var); } } class SubExpression extends SymbolExpression { public SubExpression(Expression left, Expression right) { super(left, right); } //返回left, right 表达式的值将其相减 public int interpreter(HashMap<String, Integer> var) { return super.left.interpreter(var) - super.right.interpreter(var); } } class Calculator { // 定义表达式 private Expression expression; // 构造函数传参,并解析 public Calculator(String expStr) { // expStr = a+b // 安排运算先后顺序 Stack<Expression> stack = new Stack<>(); // 表达式拆分成字符数组 char[] charArray = expStr.toCharArray();// [a, +, b] Expression left = null; Expression right = null; //遍历我们的字符数组, 即遍历 [a, +, b] //针对不同的情况,做处理 for (int i = 0; i < charArray.length; i++) { switch (charArray[i]) { case '+': // left = stack.pop();// 从 stack 取 出 left => "a" right = new VarExpression(String.valueOf(charArray[++i]));// 取出右表达式 "b" stack.push(new AddExpression(left, right));// 然后根据得到 left 和 right 构建 AddExpresson 加入stack break; case '-': // left = stack.pop(); right = new VarExpression(String.valueOf(charArray[++i])); stack.push(new SubExpression(left, right)); break; default: //如果是一个 Var 就创建要给 VarExpression 对象,并 push 到 stack stack.push(new VarExpression(String.valueOf(charArray[i]))); break; } } //当遍历完整个 charArray 数组后,stack 就得到最后 Expression this.expression = stack.pop(); } public int run(HashMap<String, Integer> var) { //最后将表达式 a+b 和 var = {a=10,b=20} //然后传递给 expression 的 interpreter 进行解释执行 return this.expression.interpreter(var); } }

 

最新回复(0)