定义
解释器模式(Interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
角色
-
AbstractExpression: 抽象表达式。声明一个抽象的解释操作,该接口为抽象语法树中所有的节点共享。
-
TerminalExpression: 终结符表达式。实现与文法中的终结符相关的解释操作。实现抽象表达式中所要求的方法。文法中每一个终结符都有一个具体的终结表达式与之相对应。
-
NonterminalExpression: 非终结符表达式。为文法中的非终结符相关的解释操作。
-
Context: 环境类。包含解释器之外的一些全局信息。
-
Client: 客户类。
优缺点
优点:
-
可扩展性比较好,灵活。
-
增加了新的解释表达式的方式。
-
易于实现文法。
缺点:
-
执行效率比较低,可利用场景比较少。
-
对于复杂的文法比较难维护。
实例(以乘除公式为例)
定义节点接口:
/**
* 节点
*/
public interface Node {
/**
* 解释
*
* @return
*/
int interpret();
}
节点具体实现类:
/**
* 值节点
*/
public class ValueNode implements Node{
private int value;
public ValueNode(int value){
this.value = value;
}
@Override
public int interpret() {
return this.value;
}
}
/**
* 符号节点抽象类
*/
public abstract class SymbolNode implements Node {
protected Node left;
protected Node right;
public SymbolNode(Node left, Node right) {
this.left = left;
this.right = right;
}
}
/**
* 乘法
*/
public class MultiplyNode extends SymbolNode{
public MultiplyNode(Node left, Node right) {
super(left, right);
}
@Override
public int interpret() {
return left.interpret() * right.interpret();
}
}
/**
* 除法
*/
public class DivisionNode extends SymbolNode {
public DivisionNode(Node left, Node right) {
super(left, right);
}
@Override
public int interpret() {
return left.interpret() / right.interpret();
}
}
计算器:
public class Calculator {
private Node node;
public void build(String statement) {
Node left,right;
Stack stack = new Stack();
String[] statementArr = statement.split(" ");
for (int i = 0; i < statementArr.length; i++) {
if (statementArr[i].equalsIgnoreCase("*")) {
left = (Node) stack.pop();
int val = Integer.parseInt(statementArr[++i]);
right = new ValueNode(val);
stack.push(new MultiplyNode(left, right));
} else if (statementArr[i].equalsIgnoreCase("/")) {
left = (Node) stack.pop();
int val = Integer.parseInt(statementArr[++i]);
right = new ValueNode(val);
stack.push(new DivisionNode(left, right));
} else {
stack.push(new ValueNode(Integer.parseInt(statementArr[i])));
}
}
this.node = (Node) stack.pop();
}
public int compute() {
return node.interpret();
}
}
测试:
public static void main(String[] args) {
String statement = "3 * 2 * 4 / 6";
Calculator calculator = new Calculator();
calculator.build(statement);
int result = calculator.compute();
System.out.println(statement + " = " + result);
}
控制台输出:
3 * 2 * 4 / 6 = 4