title: 解释器模式
author: rack-leen
avatar: /images/favicon.png
authorDesc: 脱发典范
comments: true
copyright: true
date: 2019-5-19 22:13:50
tags:
Given a language,define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language
给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
package org.example.interpreter;
import java.util.HashMap;
/**
* 抽象表达式,用来组合不同种类的解释器,形成一个表达式。
* 每种解释器就是一个算术因子,是加减乘除需要的算术因子。
*/
public abstract class Expression {
/**
* @param var String是表达式中的值,Integer是表达式中值的索引值
* @return 返回表达式计算出的值
*/
public abstract int interpreter(HashMap<String , Integer> var);
}
package org.example.interpreter;
import java.util.HashMap;
public class VarExpression extends Expression {
private String key ;
public VarExpression(String key){
this.key = key ;
}
/**
* 用来从输入的变量中获取变量在表达式中的位置
* @param var String是表达式中的值,Integer是表达式中值的索引值
* @return
*/
@Override
public int interpreter(HashMap<String, Integer> var) {
return var.get(key);
}
}
package org.example.interpreter;
import java.util.HashMap;
/**
* 符号解释器,用来解释表达式中的运算符号
*/
public abstract class SymbolExpression extends Expression {
protected Expression left ;
protected Expression right ;
public SymbolExpression(Expression left , Expression right){
this.left = left ;
this.right = right ;
}
}
package org.example.interpreter;
import java.util.HashMap;
public class AddExpression extends SymbolExpression {
/**
* 从抽象符号表达式中继承计算的左值和右值
* @param left
* @param right
*/
public AddExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
package org.example.interpreter;
import java.util.HashMap;
/**
* 减法解释器
*/
public class SubExpression extends SymbolExpression{
/**
* 从抽象符号表达式中继承计算的左值和右值
* @param left
* @param right
*/
public SubExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
package org.example.interpreter;
import java.util.HashMap;
/**
* 乘法解释器
*/
public class MulExpression extends SymbolExpression {
/**
* 从抽象符号表达式中继承计算的左值和右值
* @param left
* @param right
*/
public MulExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) * super.right.interpreter(var) ;
}
}
package org.example.interpreter;
import java.util.HashMap;
public class DivExpression extends SymbolExpression {
public DivExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) / super.right.interpreter(var) ;
}
}
package org.example.interpreter;
import java.util.HashMap;
import java.util.Stack;
public class Calculator {
private Expression expression ;
public Calculator(String expStr){
Stack<Expression> stack = new Stack<>();
Expression left = null ;
Expression right = null ;
System.out.println(expStr);
char[] array = expStr.toCharArray();
for (int i=0 ; i<array.length ; i++){
switch (array[i]){
case '+' :
left = stack.pop(); // 如果现在是+这个符号,表示前面有一个数已经入栈,这个已经入栈的数就是左值
right = new VarExpression(String.valueOf(array[++i])); //获取符号后面的数值作为右值
stack.push(new AddExpression(left , right)); // 将计算结果压栈
break;
case '-' :
left = stack.pop();
right = new VarExpression(String.valueOf(array[++i]));
stack.push(new SubExpression(left , right)) ;
break;
case '*' :
left = stack.pop();
right = new VarExpression(String.valueOf(array[++i]));
stack.push(new MulExpression(left , right)) ;
break;
case '/' :
left = stack.pop() ;
right = new VarExpression(String.valueOf(array[++i]));
stack.push(new DivExpression(left , right)) ;
break;
default:
stack.push(new VarExpression(String.valueOf(array[i]))) ;
break;
}
}
this.expression = stack.pop() ; // 将最终的运算结果赋值
}
public int run(HashMap<String , Integer> var){
return this.expression.interpreter(var) ;
}
}
public class App {
/**
* 解释器模式
* @param args
*/
public static void main(String[] args) {
/* 公式变量与数字的映射关系 */
HashMap<String, Integer> map = new HashMap<>();
map.put("a" , 100);
map.put("b" , 20);
map.put("c" , 30);
/* 需要的公式模板 */
String expStr = "a+b-c";
Calculator calculator = new Calculator(expStr);
System.out.println(calculator.run(map));
}
}