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));
    }
}