1. 类图
- AbstractExpression:解释器接口
- TerminalExpression:终结符解释器,解析句子的结束符
- NonterminalExpression:非终结符解释器,用来实现语法规则中非终结符相关的操作。可以有多种非终结符解释器
- Context:上下文,通常包含各个解释器需要的数据或是公共的功能
- Client:使用解释器的客户端,按照语言的语法表达式转换成使用解释器对象描述的抽象语法树,然后调用解释操作
2. 示例
解释器对给定语法的句子进行解析
对字符串1 + 2 + 3
进行计算
2.1 解释器接口
public interface IArithmeticExpression {
int interpreter();
}
2.2 终结符解释器
public class TerminalExpression implements IArithmeticExpression{
private int value;
public TerminalExpression(int value){this.value = value;}
@Override
public int interpreter() {
return this.value;
}
}
2.3 非终结符解释器
// 计算参数的设置
public abstract class NoterminalExpression implements IArithmeticExpression {
protected IArithmeticExpression left;
protected IArithmeticExpression right;
public NoterminalExpression(IArithmeticExpression left, IArithmeticExpression right) {
this.left = left;
this.right = right;
}
}
// 具体计算逻辑的实现
public class AddExpression extends NoterminalExpression{
public AddExpression(IArithmeticExpression left, IArithmeticExpression right) {
super(left, right);
}
@Override
public int interpreter() {
return this.left.interpreter() + this.right.interpreter();
}
}
2.4 上下文
public class Context {
private Stack<IArithmeticExpression> stack = new Stack<>();
private Predicate<String> isOperator = "+"::equals;
public Context(String expresstion){
parse(expresstion);
}
private void parse(String expresstion) {
String[] split = expresstion.split(" ");
IArithmeticExpression left,right;
for (int i = 0; i < split.length; i++) {
String element = split[i];
if (isOperator.test(element)) {
left = this.stack.pop();
right = new TerminalExpression(Integer.parseInt(split[++i]));
AddExpression addExpression = new AddExpression(left, right);
this.stack.push(addExpression);
} else {
TerminalExpression te = new TerminalExpression(Integer.parseInt(element));
this.stack.push(te);
}
}
}
public Integer getResult(){return this.stack.pop().interpreter();}
}
2.5 客户端
public class Client {
public static void main(String[] args) {
System.out.println(new Context("1 + 2 + 3").getResult());
}
}
3. 优点
- 语法可以灵活扩展
4. 缺点
- 需要构造具体的语法树,不适用于复杂的语法