介绍: 解释器是一种用的比较少的行为模式,其提供了一种解释语言的语法,或者表达式的方式。该模式定义了一个表达式的接口。
运用:
- 手机号码的验证
-
移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
-
联通:130、131、132、152、155、156、185、186
-
电信:133、153、180、189、(1349卫通)
正则表达式"((13[0-9])|(15[4,\D])|(18[0,5-9]))\d{8}$"
- xml解析
重点:
- 必须有一个抽象接口
- 构建语法树
应用场景:
- 简单的语言需要解释执行而且可以将该语言中的语句表示一个抽象的语法树。
- 对于某个特定的领域出现的不断重复的问题,可以转换成一种语法规则下的语句。
优缺点:
优点:
解决----》每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来了非常多的麻烦。
缺点:
- 解释器模式采用递归调用方法,每个非终结符表达式只关心与自己有关的表达式,每个表达式需要知道最终的结果,必须一层一层地剥茧,无论是面向过程的语言还是面向对象的语言,递归都是在必要条件下使用的,它导致调试非常复杂。想想看,如果要排查一个语法错误,我们是不是要一个一个断点的调试下去,直到最小的语法单元。
- 解释器模式由于使用了大量的循环和递归,效率是个不容忽视的问题,特别是用于解析复杂、冗长的语法时,效率是难以忍受的。
示例代码:
Node.java
package com.test.interpretor;
/**
* 抽象接口
*/
public interface Node {
public int interpret();
}
ValueNode.java
package com.test.interpretor;
/**
* 终结符
*/
public class ValueNode implements Node{
private int value;
public ValueNode(int value) {
this.value = value;
}
@Override
public int interpret() {
return value;
}
}
SymbolNode.java
package com.test.interpretor;
/**
* 非终结符
*/
public abstract class SymbolNode implements Node{
protected Node left;
protected Node right;
public SymbolNode(Node left, Node right) {
this.left = left;
this.right = right;
}
}
MulNode.java
package com.test.interpretor;
/**
* 运算乘法
*/
public class MulNode extends SymbolNode{
public MulNode(Node left, Node right) {
super(left, right);
}
@Override
public int interpret() {
return left.interpret() * right.interpret();
}
}
DivNode.java
package com.test.interpretor;
/**
* 运算除法
*/
public class DivNode extends SymbolNode{
public DivNode(Node left, Node right) {
super(left, right);
}
@Override
public int interpret() {
return left.interpret() / right.interpret();
}
}
ModNode.java
package com.test.interpretor;
/**
* 模运算
*/
public class ModNode extends SymbolNode{
public ModNode(Node left, Node right) {
super(left, right);
}
@Override
public int interpret() {
return left.interpret() % right.interpret();
}
}
Caculator.java
package com.test.interpretor;
public class Caculator {
public int build(String statement) {
Node left = null;
Node right = null;
Node lastNode = null;
String[] statements = statement.split(" ");
for (int i = 0; i < statements.length; i++) {
if (statements[i].equalsIgnoreCase("*")) {
//计算乘法
left = lastNode;
int value = Integer.parseInt(statements[++i]);
right = new ValueNode(value);
// 此时新建一个非终结符
lastNode = new MulNode(left, right);
} else if (statements[i].equalsIgnoreCase("/")) {
//计算除法
left = lastNode;
int value = Integer.parseInt(statements[++i]);
right = new ValueNode(value);
// 此时新建一个非终结符
lastNode = new DivNode(left, right);
} else if (statements[i].equalsIgnoreCase("%")) {
//计算除法
left = lastNode;
int value = Integer.parseInt(statements[++i]);
right = new ValueNode(value);
// 此时新建一个非终结符
lastNode = new ModNode(left, right);
} else {
lastNode = new ValueNode(Integer.parseInt(statements[i]));
}
}
return lastNode.interpret();
}
}
Client.java
package com.test.interpretor;
public class Client {
public static void main(String[] args) {
String contentString = "3 * 5 * 7 / 3 % 4";
Caculator caculator = new Caculator();
int result = caculator.build(contentString);
System.out.println("result = " + result);
}
}
运行结果:
> Task :interpretor:Client.main()
result = 3