定义
解释器模式:给定一门语言,定义 它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
解释器模式通常有一下几种角色:
● AbstractExpression——抽象解释器
具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和NonterminalExpression完成。 也就是下面例子的VarExpression和SymbolExpression。
● TerminalExpression——终结符表达式
实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达 式,但有多个实例,对应不同的终结符。具体到我们下面例子就是VarExpression类,表达式中的 每个终结符都在栈中产生了一个VarExpression对象。
● NonterminalExpression——非终结符表达式
文法中的每条规则对应于一个非终结表达式,具体到我们下面的例子就是加减法规则分别对 应到AddExpression和SubExpression两个类。非终结符表达式根据逻辑的复杂程度而增加,原 则上每个文法规则都对应一个非终结符表达式。
● Context——环境角色
具体到我们的例子中是采用HashMap代替。
案例
/**
* 抽象表达式类
*/
public abstract class Expression {
/**
* 解析公式和数值,其中var中的key值是公式中的参数,value值是具体的数字
* @param var
* @return
*/
public abstract int interpreter(Map<String, Integer> var);
}
/**
* 变量解析器
*/
public class VarExpression extends Expression {
//表达式的参数
private String key;
public VarExpression(String key) {
this.key = key;
}
@Override
public int interpreter(Map<String, Integer> var) {
//获取表达式参数对应的数值
return var.get(key);
}
}
/**
* 抽象运算符号解析器
*/
public abstract class SymbolExpression extends Expression {
protected Expression left;
protected Expression right;
public SymbolExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
}
/**
* 加法解析器
*/
public class AddExpression extends SymbolExpression {
public AddExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(Map<String, Integer> var) {
//相加
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
/**
* 减法解析器
*/
public class SubExpression extends SymbolExpression {
public SubExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(Map<String, Integer> var) {
//相减
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
/**
* 解释器封装类
*/
public class Calculator {
private Expression expression;
public Calculator(String expStr) {
//定义一个栈,安排运算的先后顺序
Stack<Expression> stack = new Stack<>();
//表达式拆分为字符数组
char[] charArray = expStr.toCharArray();
//运算
Expression left = null;
Expression right = null;
for (int i = 0; i < charArray.length; i++) {
switch(charArray[i]) {
//加法
case '+' :
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new AddExpression(left, right));
break;
//剪发
case '-' :
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new SubExpression(left, right));
break;
//公式中的变量
default :
stack.push(new VarExpression(String.valueOf(charArray[i])));
}
}
//把运算结果抛出来
this.expression = stack.pop();
}
//开始运算
public int run(Map<String, Integer> var) {
return this.expression.interpreter(var);
}
}
public class InterpreterPatternDemo {
public static void main(String[] args) throws IOException {
String expStr = getExpStr();
Map<String, Integer> var = getValue(expStr);
Calculator cal = new Calculator(expStr);
System.out.print("运算结果为:"+expStr +"="+cal.run(var));
}
//获得表达式
public static String getExpStr() throws IOException {
System.out.print("请输入表达式:");
return new BufferedReader(new InputStreamReader(System.in)).readLine();
}
//获得值映射
public static Map<String, Integer> getValue(String expStr) throws IOException {
Map<String, Integer> map = new HashMap<>();
for (char ch : expStr.toCharArray()) {
if (ch != '+' && ch != '-') {
System.out.print("请输入" + ch + "的值:");
String in = new BufferedReader(new InputStreamReader(System.in)).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
return map;
}
}