描述
- 对于形式变化比较多的情况下,可以把变化定义成节点,定义一个解释器,去逐步解析节点的合法性,得到最终结果。
- 比如计算器:1+2+3+4-5,1+2+3-4+5,…
- 把数字和+ - 定义成节点,由解释器去解析(提取语句规则,抽象成一种语言,然后解析这种语言的含义),得到最终结果。
定义语法规则:
- express:表达式( | :表示或的意思)
- plus:加法表达式
- minus:减法表达式
- value:最终结果
express ::= value | plus | minus
plus ::= express + express
minus ::= express - express
value ::= integer
角色
- 抽象表达式角色:定义解释器的接口,约定规范,提供解析方法:interpret。
- 终结符表达式角色:抽象表达式子类,用来实现终结符相关操作。如语法规则中的value。
- 非终结符表达式角色:抽象表达式子类,用来实现非终结符相关操作。如语法规则中的:plus等。
- 环境角色:定义解释器需要的数据,公共功能,传递所有解释器共享的数据。
- 客户端:将表达式装换为解释器对象解析的抽象语法树,让解释器解析获得结果。
实现
public class Test {
public static void main(String[] args) {
Environment environment = new Environment();
ParameterExpress a = new ParameterExpress("A");
ParameterExpress b = new ParameterExpress("B");
ParameterExpress c = new ParameterExpress("C");
ParameterExpress d = new ParameterExpress("D");
environment.add(a, 11);
environment.add(b, 2);
environment.add(c, 4);
environment.add(d, 6);
AbstractExpress express = new PlusExpress(new SubtractionExpress(new PlusExpress(a, b), c), d);
Integer interpret = express.interpret(environment);
System.out.println(express);
System.out.println(interpret);
}
}
abstract class AbstractExpress {
abstract Integer interpret(Environment environment);
}
class Environment {
private Map<ParameterExpress, Integer> parameterExpressIntegerMap = new HashMap<>();
public void add(ParameterExpress parameterExpress, Integer value) {
parameterExpressIntegerMap.put(parameterExpress, value);
}
public Integer get(ParameterExpress parameterExpress) {
return parameterExpressIntegerMap.get(parameterExpress);
}
}
class ParameterExpress extends AbstractExpress {
private String name;
ParameterExpress(String name){ this.name = name;}
@Override
Integer interpret(Environment environment) {
return environment.get(this);
}
@Override
public String toString() {
return name;
}
}
class PlusExpress extends AbstractExpress {
private AbstractExpress left;
private AbstractExpress right;
PlusExpress(AbstractExpress left, AbstractExpress right) {
this.left = left;
this.right = right;
}
@Override
Integer interpret(Environment environment) {
return left.interpret(environment) + right.interpret(environment);
}
@Override
public String toString() {
return left + "+" + right;
}
}
class SubtractionExpress extends AbstractExpress {
private AbstractExpress left;
private AbstractExpress right;
SubtractionExpress(AbstractExpress left, AbstractExpress right) {
this.left = left;
this.right = right;
}
@Override
Integer interpret(Environment environment) {
return left.interpret(environment) - right.interpret(environment);
}
@Override
public String toString() {
return left + "-" + right;
}
}

- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
优点
- 易于扩展和改变表达式规则,表达式规则编写较为符合思考逻辑。符合开闭原则。
缺点
- 复杂文法难以维护,每种规则都需要一个类,类个数太多难以管理维护,递归,执行效率较低,调试较麻烦。
使用场景
- 当语言的文法较为简单,且执行效率不是问题,简单语法规则重复出现时。