解释器模式
基本介绍原理类图解释器模式的类图实例解释器模式的代码实例解释器模式的注意事项和细节
基本介绍
在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器。解释器模式(Iterpreter Pattern):是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)应用场景
应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树一些重复出现的问题可以用一种简单的语言来表达一个简单语法需要解释的场景
这样的例子还有,比如编译器、运算表达式计算、正则表达式、机器人等。
原理类图
对原理类图的说明-即(解释器模式的角色及职责)
Context:是环境角色,含有解释器之外的全局信息AbstractExpression:抽象表达式,声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享TerminalExpression:为终结符表达式,实现与文法中的终结符相关的解释操作。NonTermialExpression:为非终结符表达式,为文法中的非终结符实现解释操作说明:输入Context 和 TerminalExpression 信息通过Client输入即可
解释器模式的类图实例
解释器模式的代码实例
public abstract class Expression {
public abstract int interpreter(HashMap
<String, Integer> var
);
}
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(this.key
);
}
}
public class SymbolExpression extends Expression {
protected Expression left
;
protected Expression right
;
public SymbolExpression(Expression left
, Expression right
) {
this.left
= left
;
this.right
= right
;
}
@Override
public int interpreter(HashMap
<String, Integer> var
) {
return 0;
}
}
public class AddExpression extends SymbolExpression {
public AddExpression(Expression left
, Expression right
) {
super(left
, right
);
}
public int interpreter(HashMap
<String, Integer> var
) {
return super.left
.interpreter(var
) + super.right
.interpreter(var
);
}
}
public class SubExpression extends SymbolExpression {
public SubExpression(Expression left
, Expression right
) {
super(left
, right
);
}
public int interpreter(HashMap
<String, Integer> var
) {
return super.left
.interpreter(var
) - super.right
.interpreter(var
);
}
}
public class Calculator {
private Expression expression
;
public Calculator(String expStr
) {
Stack
<Expression> stack
= new Stack<>();
char[] charArray
= expStr
.toCharArray();
Expression left
= null
;
Expression 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
])));
break;
}
}
this.expression
= stack
.pop();
}
public int run(HashMap
<String, Integer> var
) {
return this.expression
.interpreter(var
);
}
}
客户端
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
));
}
private static String
getExpStr() throws IOException
{
System
.out
.print("请输入表达式:");
return (new BufferedReader(new InputStreamReader(System
.in
))).readLine();
}
private static HashMap
<String, Integer> getValue(String expStr
) throws IOException
{
HashMap
<String, Integer> map
= new HashMap<>();
for (char ch
: expStr
.toCharArray()) {
if (ch
!= '+' && ch
!= '-') {
if (!map
.containsKey(String
.valueOf(ch
))) {
System
.out
.println("请输入" + String
.valueOf(ch
) + "的值:");
String in
= (new BufferedReader(new InputStreamReader(System
.in
))).readLine();
map
.put(String
.valueOf(ch
), Integer
.valueOf(in
));
}
}
}
return map
;
}
}
解释器模式的注意事项和细节
当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性应用场景:编译器、运算表达式计算、正则表达式、机器人等使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低。