给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
语言:指的是使用规定格式和文法的一类字符组合
文法:简单点说就是我们俗称的“语法规则”
解释器模式的本质:分离实现,解释执行
当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使 用解释器模式。而当存在以下情况时该模式效果最好:
假设我们输入的值是一个仅支持加减法的字符串,我们需要计算出该串的计算结果 a + b +c +d +e + f;而变量 a-f 对应的值通过一个 hashmap 给出

终结符与非终结符的划分依据:
终结符表达式(TerminalExpression):实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。
终结符一半是文法中的运算单元,比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式
在算术运算中,终结符表达式一般代表数字,因为数字没有办法再分,没有子类,所以是终结符
非终结符表达式(NonterminalExpression):文法中的每条规则对应于一个非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,+ 就是非终结符,解析+的解释器就是一个非终结符表达式
非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式
在算术运算中,非终结表达式一般表示运算符,因为运算符需要操作数,不能单独操作,所以各种运算符又代表加减乘除表达式,因此是非终结式的
AbstractExpression
- package com.designer.interpreter.AbstractExpression;
-
- import java.util.HashMap;
-
- /**
- * 抽象表达式,声明解释操作
- */
- public abstract class AbstractExpression {
-
- public abstract int interprete(HashMap<String, Integer> values);
- }
SymbolExpression
- package com.designer.interpreter.NonterminalExpression;
-
- import com.designer.interpreter.AbstractExpression.AbstractExpression;
-
- /**
- * 非终结符表达式,运算符(此处为加法和减法)的抽象父类,真正的解释操作由其子类来实现
- */
- public abstract class SymbolExpression extends AbstractExpression {
-
- protected AbstractExpression left;
- protected AbstractExpression right;
-
- // 非终结符表达式的解释操作只关心自己左右两个表达式的结果
- public SymbolExpression(AbstractExpression left, AbstractExpression right) {
- this.left = left;
- this.right = right;
- }
- }
AddExpression
- package com.designer.interpreter.NonterminalExpression;
-
- import com.designer.interpreter.AbstractExpression.AbstractExpression;
- import java.util.HashMap;
-
- /**
- * NonterminalExpression(非终结符表达式)
- * 加法表达式
- */
- public class AddExpression extends SymbolExpression{
-
- public AddExpression(AbstractExpression left, AbstractExpression right) {
- super(left, right);
- }
-
- @Override
- public int interprete(HashMap<String, Integer> values) {
- return super.left.interprete(values) + super.right.interprete(values);
- }
- }
SubExpression
- package com.designer.interpreter.NonterminalExpression;
-
- import com.designer.interpreter.AbstractExpression.AbstractExpression;
- import java.util.HashMap;
-
- /**
- * NonterminalExpression(非终结符表达式)
- * 减法表达式
- */
- public class SubExpression extends SymbolExpression {
-
- public SubExpression(AbstractExpression left, AbstractExpression right) {
- super(left, right);
- }
-
- // 左右两个表达式相减
- public int interprete(HashMap<String, Integer> values) {
- return super.left.interprete(values) - super.right.interprete(values);
- }
- }
VarExpression
- package com.designer.interpreter.TerminalExpression;
-
- import com.designer.interpreter.AbstractExpression.AbstractExpression;
- import java.util.HashMap;
-
- /**
- * 终结符表达式,代表参加运算的元素对象
- */
- public class VarExpression extends AbstractExpression {
-
- private String key;
-
- public VarExpression(String key) {
- this.key = key;
- }
-
- //
- public int interprete(HashMap<String, Integer> values) {
- return (Integer) values.get(this.key);
- }
- }
Calculator
- package com.designer.interpreter.Context;
-
- import com.designer.interpreter.AbstractExpression.AbstractExpression;
- import com.designer.interpreter.NonterminalExpression.AddExpression;
- import com.designer.interpreter.NonterminalExpression.SubExpression;
- import com.designer.interpreter.TerminalExpression.VarExpression;
- import java.util.HashMap;
- import java.util.Stack;
-
- /**
- * Context(上下文)
- */
- 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 '+': // 加法
- 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 calculate(HashMap<String, Integer> var) {
- return this.expression.interprete(var);
- }
- }
Test
- package com.designer.interpreter;
-
- import com.designer.interpreter.Context.Calculator;
- import java.util.HashMap;
-
- public class Test {
-
- public static void main(String[] args) {
-
- HashMap<String, Integer> values = new HashMap<String, Integer>();
- values.put("a", 10);
- values.put("b", 20);
- values.put("c", 30);
- values.put("d", 40);
- values.put("e", 50);
- values.put("f", 60);
-
- Calculator calc = new Calculator("a+b+c+d+e+f");
- int result = calc.calculate(values);
-
- System.out.println("a+b+c+d+e+f=" + result);
- }
- }
