定义解释器模式(Interpreter Pattern):是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)
在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器
下图是解释器模式的UML结构图。
解释器模式主要包含如下几个角色:
AbstractExpression: 抽象表达式。声明一个抽象的解释操作,该接口为抽象语法树中所有的节点共享。
TerminalExpression: 终结符表达式。实现与文法中的终结符相关的解释操作。实现抽象表达式中所要求的方法。文法中每一个终结符都有一个具体的终结表达式与之相对应。
NonterminalExpression: 非终结符表达式。为文法中的非终结符相关的解释操作。
Context: 环境类。包含解释器之外的一些全局信息。
Client: 客户类。
抽象语法树描述了如何构成一个复杂的句子,通过对抽象语法树的分析,可以识别出语言中的终结符和非终结符类。 在解释器模式中由于每一种终结符表达式、非终结符表达式都会有一个具体的实例与之相对应,所以系统的扩展性比较好。
现在我们用解释器模式来实现一个基本的递增递减操作。
package com.dongguo.interpreter;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:47
* @description: 上下文环境
*/
public class Context {
private String input;
private int output;
public Context(String input) {
this.input = input;
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public int getOutput() {
return output;
}
public void setOutput(int output) {
this.output = output;
}
}
package com.dongguo.interpreter;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:48
* @description: 抽象解释器
*/
public abstract class Expression {
public abstract void interpret(Context context);
}
package com.dongguo.interpreter;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:48
* @description: 递增解释器
*/
public class PlusExpression extends Expression {
public void interpret(Context context){
System.out.println("自动递增");
//获得上下文环境
String input=context.getInput();
//进行类转换
int intput=Integer.parseInt(input);
++intput;
//对上下文环境重新进行复制
context.setInput(String.valueOf(intput));
context.setOutput(intput);
}
}
package com.dongguo.interpreter;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:48
* @description: 递减解释器
*/
public class MinusExpression extends Expression {
@Override
public void interpret(Context context) {
System.out.println("自动递减");
//获得上下文环境
String input=context.getInput();
//进行类转换
int intput=Integer.parseInt(input);
--intput;
context.setInput(String.valueOf(intput));
context.setOutput(intput);
}
}
package com.dongguo.interpreter;
/**
* @author Dongguo
* @date 2021/8/23 0023-9:49
* @description:
*/
public class Client {
public static void main(String[] args) {
String number="10";
Context context=new Context(number);
//递增
Expression expression=new PlusExpression();
expression.interpret(context);
System.out.println(context.getOutput());
//递减
Expression expression1=new MinusExpression();
expression1.interpret(context);
System.out.println(context.getOutput());
}
}
运行结果:
自动递增
11
自动递减
10
优点
1、 可扩展性比较好,灵活。
2、 增加了新的解释表达式的方式。
3、 易于实现文法。
缺点 1、 执行效率比较低,可利用场景比较少。
2、 对于复杂的文法比较难维护。
模式适用场景 1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
2、一些重复出现的问题可以用一种简单的语言来进行表达。
3、文法较为简单。
模式总结 1、在解释器模式中由于语法是由很多类表示的,所以可扩展性强。
2、虽然解释器的可扩展性强,但是如果语法规则的数目太大的时候,该模式可能就会变得异常复杂。所以解释器模式适用于文法较为简单的。
3、解释器模式可以处理脚本语言和编程语言。常用于解决某一特定类型的问题频繁发生情况。