(21) Interpreter Mode
The Interpreter Pattern, given a language, defines its grammatical representation, and defines an interpreter that uses that identity to interpret sentences in the language. If a particular type of problem occurs frequently enough, it may be worth expressing the instances of the problem as sentences in a simple language. This makes it possible to build an interpreter that solves the problem by interpreting these sentences.
1. Design principles of the interpreter pattern
1, abstract expression (IExpression):, define the abstract method interpret;
2, Terminal Expression (TerminalExpression): realizes the interpretation operation related to the terminal symbol in the grammar;
3. Nonterminal Expression (NonterminalExpression): Realize the interpretation operations related to nonterminals in the grammar;
4. Context: global information outside the interpreter.
2. Simple example
Use interpreter mode to encapsulate addition, subtraction, multiplication and division operations.
public interface IMathInterpreter {
/**
* 顶级方法
* @return
*/
int interpreter();
}
public class NumInterpreter implements IMathInterpreter {
public int value;
public NumInterpreter(int value) {
this.value = value;
}
@Override
public int interpreter() {
return this.value;
}
}
public class AddInterpreter extends Interpreter {
/**
* 子类继承父类,可以重写父类方法,必须重写构造方法。
* @param left
* @param right
*/
public AddInterpreter(IMathInterpreter left, IMathInterpreter right) {
super(left, right);
}
@Override
public int interpreter() {
return this.left.interpreter()+this.right.interpreter();
}
}
public class SubInterpreter extends Interpreter {
public SubInterpreter(IMathInterpreter left, IMathInterpreter right) {
super(left, right);
}
@Override
public int interpreter() {
return this.left.interpreter()-this.right.interpreter();
}
}
public class MultiInterpreter extends Interpreter {
public MultiInterpreter(IMathInterpreter left, IMathInterpreter right) {
super(left, right);
}
@Override
public int interpreter() {
return this.left.interpreter()*this.right.interpreter();
}
}
public class DivInterpreter extends Interpreter {
public DivInterpreter(IMathInterpreter left, IMathInterpreter right) {
super(left, right);
}
@Override
public int interpreter() {
return this.left.interpreter()/this.right.interpreter();
}
}
public class Calculator {
private Stack<IMathInterpreter> stack = new Stack<>();
public Calculator(String expression){
this.parse(expression);
}
/**
* 此处仅考虑简单计算,从左至右直接算
* @param expression
*/
public void parse(String expression){
String[] ele = expression.split(" ");
IMathInterpreter left,right;
for(int i=0;i<ele.length;i++){
String operator = ele[i];
if(OperatorUtils.ifOperator(operator)){
// 是操作符,将前一个数字弹出
left = stack.pop();
right = new NumInterpreter(Integer.valueOf(ele[++i]));
System.out.println("出栈:"+left.interpreter()+"和"+right.interpreter());
// 将计算结果压入栈中
// 通过传递待计算项,由解释器复制解释
this.stack.push(OperatorUtils.getInterpreter(left,right,operator));
System.out.println("运算符:"+operator);
}else {
NumInterpreter numInterpreter = new NumInterpreter(Integer.valueOf(ele[i]));
this.stack.push(numInterpreter);
System.out.println("入栈:"+numInterpreter.interpreter());
}
}
}
public int calculate(){
// 计算时直接弹出结果即可
return this.stack.pop().interpreter();
}
}
public class OperatorUtils {
public static boolean ifOperator(String symbol){
return (symbol.equals("+")||symbol.equals("-")||symbol.equals("*")||symbol.equals("/"));
}
public static Interpreter getInterpreter(IMathInterpreter left, IMathInterpreter right,String symbol){
if("+".equals(symbol)){
return new AddInterpreter(left, right);
}else if("-".equals(symbol)){
return new SubInterpreter(left, right);
}else if ("*".equals(symbol)){
return new MultiInterpreter(left, right);
}else if ("/".equals(symbol)){
return new DivInterpreter(left, right);
}
return null;
}
}
public class Client {
public static void main(String[] args) {
System.out.println(new Calculator("3 + 4").calculate());
}
}
3. Evaluation of Interpreter Mode
Interpreter mode increases system complexity with the complexity of the grammar. Good extensibility, easy to implement simple grammar.