适用场景
提供一种方式,用来定义语言的文法表达,并解释执行。
类图
实例代码
这个地方,定义了一个加法表达式,为了简单起见,只有加法,没有其他运算,且假设每个变量名长度只有一个字母。
AbstractExpression:
public abstract class AbstractExpression {
abstract int interpret(Context context);
}
TerminalExpression:
public class TerminalExpression extends AbstractExpression{
private String variable_name;
public TerminalExpression(String variable_name) {
this.variable_name = variable_name;
}
@Override
int interpret(Context context) {
return context.get(variable_name);
}
}
AddExpression:
public class AddExpression extends AbstractExpression {
AbstractExpression expression1;
AbstractExpression expression2;
public AddExpression(AbstractExpression expression1, AbstractExpression expression2) {
this.expression1 = expression1;
this.expression2 = expression2;
}
@Override
int interpret(Context context) {
return expression1.interpret(context)+expression2.interpret(context);
}
}
Context:
import java.util.Map;
import java.util.Stack;
/**
* Created by windkl on 2017/3/26.
*/
public class Context {
Map<String,Integer> variable_table;
AbstractExpression expression;
public Context(String expression, Map<String,Integer> variable_table){
this.variable_table=variable_table;
Stack<AbstractExpression> stack=new Stack<>();
for(int i=0;i<expression.length();i++){
switch (expression.charAt(i)){
case '+':
AbstractExpression left=stack.pop();
i++;
AbstractExpression right=new TerminalExpression(expression.charAt(i)+"");
AddExpression addExpression=new AddExpression(left,right);
stack.push(addExpression);
break;
default:
AbstractExpression variable=new TerminalExpression(expression.charAt(i)+"");
stack.push(variable);
}
}
if(stack.size()==1)
this.expression=stack.pop();
}
public int calculate(){
return expression.interpret(this);
}
public void add(String variable_name, int value){
if(!variable_table.containsKey(variable_name))
variable_table.put(variable_name,value);
}
public int get(String variable_name){
return variable_table.get(variable_name);
}
}
Client:
import java.util.HashMap;
import java.util.Map;
/**
* Created by windkl on 2017/3/26.
*/
public class Client {
public static void main(String[] args){
Map<String,Integer> variables=new HashMap<>();
variables.put("a",3);
variables.put("b",5);
variables.put("c",8);
Context context=new Context("a+b+c",variables);
System.out.print(context.calculate());
}
}
后续思考:认为parse表达式构建Expression的部分,不应该放在Context中,Context就应该是一个变量表,提供put和add方法。可以额外创建一个Parser类执行parse的任务,Client调用这个Parser得到对应计算表达式的Expression,然后Client调用expression.interpreter(context).
又想了一下,感觉可以用Builder Pattern来解决Expression的问题。