设计模式之 Interpreter(解释器) 通俗理解

1 Interpreter定义:

定义语言的文法 ,并且建立一个解释器来解释该语言中的句子。通俗来讲就是定义一套规则,然后有个工具类,根据你传入的参数就知道你表达的意思。
Interpreter 似乎使用面不是很广,它描述了一个语言解释器是如何构成的。

 2 如何使用?

举例 计算器的实现

package xx.study.design.interpreter;

public class IterpreterDemo {

        public static void main(String[] args) {
            ParserInterpreter interpreter = new ParserInterpreter();
            double result = interpreter.calculate("2*(3+1+1)-4*2+3");
            System.out.println("计算结果为: " + result);
        }


}
package xx.study.design.interpreter;

/**
 * 定义Interpreter接口
 */
public interface Interpreter {
    double calculate(String expression);
}


package xx.study.design.interpreter;

import java.util.LinkedList;

/**
 * 解析器,构造语法树
 *
 *
 */
public class ParserInterpreter implements Interpreter {


    public double calculate(String expression) { //1 * (2 + 3)
        StringBuilder number = new StringBuilder();
        LinkedList<Interpreter> interpreters = new LinkedList<Interpreter>();
        LinkedList<Character> operators = new LinkedList<Character>();
        for (char ch : expression.toCharArray()) {
            if (isOperator(ch)) {
                //将之前的数字入栈
                if (number.length() > 0) {
                    interpreters.add(new Number(Double.parseDouble(number.toString())));
                    number.setLength(0);
                }
                //组装表达式
                while (interpreters.size() >= 2) {
                    Character lastOp = operators.getLast();
                    //碰到左括号
                    if (isOpenParen(lastOp)) {
                        break;
                    }
                    //碰到了运算符,但下一个运算符优先级是否更高?
                    if (rightOperatorGreater(lastOp, ch)) {
                        break;
                    }
                    Interpreter right = interpreters.removeLast();
                    Interpreter left = interpreters.removeLast();
                    Interpreter interpreter = constructExpression(left,
                            operators.removeLast(), right);
                    interpreters.addLast(interpreter);
                }
                if (isCloseParen(ch)) {
                    //碰到右括号,直接去掉左括号
                    operators.removeLast();
                } else {
                    //非右括号,直接进栈
                    operators.addLast(ch);
                }
            } else {
                number.append(ch);
            }
        }
        //最后是数字,如1*2+3
        if (number.length() > 0) {
            interpreters.add(new Number(Double.parseDouble(number.toString())));
            number.setLength(0);
        }
        //最后一次运算
        if (operators.size() > 0) {
            Interpreter right = interpreters.removeLast();
            Interpreter left = interpreters.removeLast();
            Interpreter interpreter = constructExpression(left,
                    operators.removeLast(), right);
            interpreters.addLast(interpreter);
        }
        //调用组装好的树
        return interpreters.pop().calculate(expression);
    }

    /**
     * 右边运算符是否优先级更高
     * @param leftOp
     * @param rightOp
     * @return
     */
    private boolean rightOperatorGreater(char leftOp, char rightOp) {
        if (rightOp == '*' || rightOp == '/') {
            return leftOp == '+' || leftOp == '-';
        }
        return false;
    }

    private boolean isOperator(char ch) {
        return ch == '-' || ch == '+' || ch == '/' || ch == '*' || ch == '(' || ch ==')';
    }

    private boolean isOpenParen(char ch) {
        return ch == '(';
    }

    private boolean isCloseParen(char ch) {
        return ch == ')';
    }

    private Interpreter constructExpression(Interpreter left, char op, Interpreter right) {
        switch (op) {
            case '+' :
                return new Add(left, right);
            case '*' :
                return new Multiply(left, right);
            case '-' :
                return new Minus(left, right);
            case '/' :
                return new Divide(left, right);
            default:
                break;
        }
        return null;
    }

}
package xx.study.design.interpreter;

public class Number implements Interpreter {

    private double number;

    public Number(double number) {
        super();
        this.number = number;
    }

    public double calculate(String expression) {
        return number;
    }

}
package xx.study.design.interpreter;

/**
 * 实现加法操作,注意这里组合了其他的Interpreter对象,而不是直接操作数字。
 * left和right即可能是数字,也可能是其他的操作。
 */
public class Add implements Interpreter {

    private Interpreter left;

    private Interpreter right;

    public Add(Interpreter left, Interpreter right) {
        this.left = left;
        this.right = right;
    }


    public double calculate(String expression) {
        return left.calculate(expression) + right.calculate(expression);
    }

}
package xx.study.design.interpreter;

/**
 * 实现减法操作,注意这里组合了其他的Interpreter对象,而不是直接操作数字。
 * left和right即可能是数字,也可能是其他的操作。
 */
public class Minus implements Interpreter {

    private Interpreter left;

    private Interpreter right;

    public Minus(Interpreter left, Interpreter right) {
        this.left = left;
        this.right = right;
    }


    public double calculate(String expression) {
        return left.calculate(expression)-right.calculate(expression);
    }

}
package xx.study.design.interpreter;

/**
 * 实现乘法操作,注意这里组合了其他的Interpreter对象,而不是直接操作数字。
 * left和right即可能是数字,也可能是其他的操作。
 */
public class Multiply implements Interpreter {

    private Interpreter left;

    private Interpreter right;

    public Multiply(Interpreter left, Interpreter right) {
        this.left = left;
        this.right = right;
    }


    public double calculate(String expression) {
        return left.calculate(expression)*right.calculate(expression);
    }

}
package xx.study.design.interpreter;

/**
 * 实现除法操作,注意这里组合了其他的Interpreter对象,而不是直接操作数字。
 * left和right即可能是数字,也可能是其他的操作。
 */
public class Divide implements Interpreter {

    private Interpreter left;

    private Interpreter right;

    public Divide(Interpreter left, Interpreter right) {
        this.left = left;
        this.right = right;
    }


    public double calculate(String expression) {
        return left.calculate(expression)/right.calculate(expression);
    }

}

猜你喜欢

转载自blog.csdn.net/h4241778/article/details/107586577
今日推荐