解释器模式
解释器模式(Interpreter Pattern)是一种按照规定语法进行解析的方案,在现在项目中使 用较少,其定义如下:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language。
优点
解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改 相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。
缺点
- 解释器模式会引起类膨胀。
- 解释器模式采用递归调用方法。
- 效率问题:解释器模式由于使用了大量的循环和递归,效率是一个不容忽视的问题,特别是一用于 解析复杂、冗长的语法时,效率是难以忍受的。
使用场景
- 重复发生的问题可以使用解释器模式
- 一个简单语法需要解释的场景
例子:模拟计算表达式
- 抽象表达式
/**
* 抽象表达式
*
* @author admin
*/
public abstract class Expression {
/**
* 解析公式和数值,其中var中的key值是公式中的参数,value值是具体的数字
*
* @param var 参数
* @return 返回值
*/
public abstract int interpreter(HashMap<String, Integer> var);
}
- 变量解析器
import java.util.HashMap;
/**
* 变量解析器
*
* @author admin
*/
public class VarExpression extends Expression {
private String key;
public VarExpression(String key) {
this.key = key;
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return var.get(key);
}
}
- 抽象运算符号解析器
/**
* 抽象运算符号解析器
*
* @author admin
*/
public abstract class SymbolExpression extends Expression {
protected Expression left;
protected Expression right;
/**
* 所有的解析公式都应只关心自己左右两个表达式的结果
*
* @param left 左侧表达式
* @param right 右侧表达式
*/
public SymbolExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
}
- 加法解析器
import java.util.HashMap;
/**
* 加法解析器
*
* @author admin
*/
public class AddExpression extends SymbolExpression {
public AddExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
- 减法解析器
import java.util.HashMap;
/**
* 减法解析器
*
* @author admin
*/
public class SubExpression extends SymbolExpression {
public SubExpression(Expression left, Expression right) {
super(left, right);
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
- 解析器封装类
import java.util.HashMap;
import java.util.Stack;
/**
* 解析器封装类
*
* @author admin
*/
public class Calculator {
//定义表达式
private Expression expression;
//构造函数传参,并解析
public Calculator(String expStr) {
//定义一个栈,安排运算的先后顺序
Stack<Expression> stack = new Stack<>();
//表达式拆分为字符数组
char[] charArray = expStr.toCharArray();
//运算
Expression left;
Expression right;
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(HashMap<String, Integer> var) {
return this.expression.interpreter(var);
}
}
- 客户端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class Client {
//运行四则运算
public static void main(String[] args) throws IOException {
String expStr = getExpStr();
//赋值
HashMap<String, Integer> var = getValue(expStr);
Calculator cal = new Calculator(expStr);
System.out.println("运算结果为:" + expStr + "=" + cal.run(var));
}
//获得表达式
public static String getExpStr() throws IOException {
System.out.print("请输入表达式:");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
//获得值映射
public static HashMap<String, Integer> getValue(String exprStr) throws IOException {
HashMap<String, Integer> map = new HashMap<>();
//解析有几个参数要传递
for (char ch : exprStr.toCharArray()) {
if (ch != '+' && ch != '-') {
//解决重复参数的问题
if (!map.containsKey(String.valueOf(ch))) {
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
}
return map;
}
}
标签:解释器,right,HashMap,模式,var,设计模式,Expression,public,left
From: https://www.cnblogs.com/kouhao/p/17579626.html