您的位置:首页 > 其它

设计模式学习笔记(24)——解释器模式

2015-05-25 17:21 302 查看
一、模式定义
所谓解释器模式就是定义语言的文法,并且建立一个解释器来解释该语言中的句子。

在这里我们将语言理解成使用规定格式和语法的代码。

在前面我们知道可以构建解释器来解决那些频繁发生的某一特定类型的问题,在这我们将这些问题的实例表述为一个语言中句子。例如我经常利用正则表达式来检测某些字符串是否符合我们规定的格式。这里正则表达式就是解释器模式的应用,解释器为正则表达式定义了一个文法,如何表示一个特定的正则表达式,以及如何解释这个正则表达式。

解释器模式描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发的编译器中。它描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。

在解释器模式中除了能够使用文法规则来定义一个语言,还有通过一个更加直观的方法来表示——使用抽象语法树。抽象语法树能够更好地,更直观地表示一个语言的构成,每一颗抽象语法树对应一个语言实例。

二、模式结构



解释器模式主要包含如下几个角色:

AbstractExpression: 抽象表达式。声明一个抽象的解释操作,该接口为抽象语法树中所有的节点共享。

TerminalExpression: 终结符表达式。实现与文法中的终结符相关的解释操作。实现抽象表达式中所要求的方法。文法中每一个终结符都有一个具体的终结表达式与之相对应。

NonterminalExpression: 非终结符表达式。为文法中的非终结符相关的解释操作。

Context: 环境类。包含解释器之外的一些全局信息。

Client: 客户类。

抽象语法树描述了如何构成一个复杂的句子,通过对抽象语法树的分析,可以识别出语言中的终结符和非终结符类。 在解释器模式中由于每一种终结符表达式、非终结符表达式都会有一个具体的实例与之相对应,所以系统的扩展性比较好。

三、模式实现

Context : 包含解释器之外的一些全局信息。

class Context {

private String input;

private String output;

public void setInput(String input) {

this.input = input;

}

public String getInput() {

return this.input;

}

public void setOutput(String output) {

this.output = output;

}

public String getOutput() {

return this.output;

}

}

AbstractExpression : 声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。

abstract class AbstractExpression {
public abstract void Interpret(Context context);
}

TerminalExpression : 实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口,主要是一个 Interprete()方法。
文法中的每一个终结符都有一个具体终结表达式与之对应。

class TerminalExpression extends AbstractExpression {

@Override

public void Interpret(Context context) {

context.setOutput("终端" + context.getInput());

System.out.println(context.getInput() + "经过终端解释器解释为:" + context.getOutput());

}

}

NonterminalExpression : 实现与文法中的非终结符相关联的解释操作。对文法中的每一条规则R1,R2......Rn都需要一个具体的非终结符表达式类。通过实现抽象表达式的 Interpret 方法实现解释操作。

class NonterminalExpression extends AbstractExpression {

@Override

public void Interpret(Context context) {

context.setOutput("非终端" + context.getInput());

System.out.println(context.getInput() + "经过非终端解释器解释为:" + context.getOutput());

}

}

测试代码

public class InterpreterPattern {

public static void main(String[] args) {

Context context = new Context();

context.setInput("ABC");

AbstractExpression expression1 = new TerminalExpression();

expression1.Interpret(context);

AbstractExpression expression2 = new NonterminalExpression();

expression2.Interpret(context);

}

}

运行结果

ABC经过终端解释器解释为:终端ABC
ABC经过非终端解释器解释为:非终端ABC

[b]四、使用场景[/b]
1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。

2、一些重复出现的问题可以用一种简单的语言来进行表达。

3、文法较为简单。

[b]五、模式总结[/b]
1、在解释器模式中由于语法是由很多类表示的,所以可扩展性强。

2、虽然解释器的可扩展性强,但是如果语法规则的数目太大的时候,该模式可能就会变得异常复杂。所以解释器模式适用于文法较为简单的。

3、解释器模式可以处理脚本语言和编程语言。常用于解决某一特定类型的问题频繁发生情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: