一、问题
1、通过解释器模式来实现四则运算,比如计算a+b+c的值
2、先输入表达式的形式,比如a+b+c+d+e 要求表达式的字母不能重复
3、最后求结果
二、基本介绍
1、在编译原理中,一个算术表达式通过词法分析形成词法单元,而后这些词法单元再通过与法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析和语法分析可以看作是解释器模式。
2、解释器模式(Interpreter Pattern):是指给定一个语言(表达式),定义他的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)
3、场景
1)应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树
2)一些重复出现的问题可以用一种简单的语言来表达
3、一个简单的语法需要解释场景
4、编译器、运算表达式、正则表达式、机器人。
三、说明 与代码
1、Context 是环境角色,含有解释器之外的全局信息。
2、AbstractExpression 抽象表达式,声明一个抽象的操作,这个方法为抽象语法树中所以的节点所共享。
3、TerminationExpression 为终结表达式,实现与文法的终结符相关的解释操作
4、NonTerminalExpression 为非终结符表达式,为文法的非终结实现解释操作
package com.hao.demo.design.interpreter;
import java.util.HashMap;
/**
* @author
* @date 2020-05-28
*/
// 抽象类表达式 HashMap 可以获取到各个变量的值
public abstract class AbstractExpression {
// a + b - c
// 解释公式和值 key 就是公式 value 就是具体的值
// HashMap {a=10, b=25}
public abstract int interpreter(HashMap<String, Integer> var);
}
package com.hao.demo.design.interpreter;
import java.util.HashMap;
/**
* @author
* @date 2020-05-28
*/
public class AddExpression extends SymbolExpression {
public AddExpression(AbstractExpression left, AbstractExpression right) {
super(left, right);
}
/**
* 1、处理相加
* 2、super.left.interpreter(var) :返回left 表达式对应的值a=10
* 3、super.right.interpreter(var) 返回右表达式对应的值
*/
@Override
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
package com.hao.demo.design.interpreter;
import java.util.HashMap;
import java.util.Stack;
/**
* @author
* @date 2020-05-28
*/
public class Calculator {
// 定义表达式
private AbstractExpression expression;
// 构造参数传入并解析
public Calculator(String expStr) {
// 安排运算先后顺序
Stack<AbstractExpression> stack = new Stack<>();
char[] charArray = expStr.toCharArray();
AbstractExpression left = null;
AbstractExpression right = null;
// 遍历数组
// 针对不同情况做不同的处理
for (int i = 0; i < charArray.length; i++) {
switch (charArray[i]) {
case '+': // a + b
left = stack.pop(); // a
right = new VarExpression(String.valueOf(charArray[++i])); // b
stack.push(new AddExpression(left, right)); // a+b
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])));
break;
}
}
// 遍历完整个数组后栈中就得到了整体的expression
this.expression = stack.pop();
}
public int run(HashMap<String, Integer> var) {
// 最后将表达式a+b和var
return this.expression.interpreter(var);
}
}
package com.hao.demo.design.interpreter;
import java.util.HashMap;
/**
* @author
* @date 2020-05-28
*/
public class SubExpression extends SymbolExpression {
public SubExpression(AbstractExpression left, AbstractExpression right) {
super(left, right);
}
/**
* 求出相减后的值
* @param var
* @return
*/
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
package com.hao.demo.design.interpreter;
import java.util.HashMap;
/**
* @author
* @date 2020-05-28
*/
public class SymbolExpression extends AbstractExpression{
protected AbstractExpression left; // 左表达式
protected AbstractExpression right; // 右表达式
public SymbolExpression(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
/**
* 让子类具体的实现 这是一个默认实现
* @param var
* @return
*/
@Override
public int interpreter(HashMap<String, Integer> var) {
return 0;
}
}
package com.hao.demo.design.interpreter;
import java.util.HashMap;
/**
* 变量解释器
* @author
* @date 2020-05-28
*/
public class VarExpression extends AbstractExpression{
private String key;
public VarExpression(String key) {
this.key = key;
}
/**
* 根据var 返回变量的表达式
* @param var
* @return
*/
@Override
public int interpreter(HashMap<String, Integer> var) {
return var.get(this.key);
}
}
package com.hao.demo.design.interpreter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
/**
* @author
* @date 2020-05-28
*/
public class Client {
public static void main(String[] args) throws IOException {
String expStr = getExpStr();
HashMap<String, Integer> var = getValue(expStr);
Calculator calculator = new Calculator(expStr);
System.out.println("运算结果" + expStr + calculator.run(var));
}
// 获得表达式
public static String getExpStr() throws IOException {
System.out.println("请输入表达式");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
// 等待完成
// 获得映射值
public static HashMap<String, Integer> getValue(String expStr) throws IOException {
HashMap<String, Integer> map = new HashMap<>(16);
for (char ch :expStr.toCharArray()) {
if (ch != '+' && ch != '-') {
if (!map.containsKey(String.valueOf(ch))) {
System.out.println("请输入"+ ch + "的值");
String in = (new BufferedReader((new InputStreamReader(System.in)))).readLine();
expStr = in;
}
}
}
return map;
}
}