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