[设计模式笔记]三. 行为型模式--17. Interpreter模式(解释器模式)(一)

来源:互联网 发布:六年级上册语文优化 编辑:程序博客网 时间:2024/06/06 00:36

行为型模式--Interpreter(解释器)类行为型模式

一. 意图


       给定一个语言定义它的文法的一种表示并定义一个解释器这个解释器使用该表示来解释语言中的句子.


二. 适用性

       如果一种特定类型的问题发生的频率足够高那么可能就值得将该问题的各个实例表述为一个简单语言中的句子这样就可以构建一个解释器该解释器通过解释这些句子来解决该问题

当有一个语言需要解释执行并且你可将该语言中的句子表示为一个抽象语法树时可使用解释器模式


三. 模式结构


图1 



四. 角色说明


AbstractExpression(抽象表达式)

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

TerminalExpression(终结符表达式)

—实现与文法中的终结符相关联的解释操作.

—一个句子中的每个终结符需要该类的一个实例.

NonTerminalExpression(非终结符表达式)

—对文法中的每一条规则都对应一个NonTerminalExpression类。

—为从R1Rn的每个符号都维护一个AbstractExpression类型的实例变量。

—为文法中的非终结符实现解释(Interpret)操作解释(Interpret)一般要递归地调用表示R1Rn的那些对象的解释操作.

Context(上下文)

—包含解释器之外的一些全局信息.

Client(客户)

—构建(或被给定)表示该文法定义的语言中一个特定的句子的抽象语法树该抽象语法树由NonTerminalExpressionTerminalExpression的实例装配而成.

—调用解释操作.

协作

Client构建(或被给定)一个句子它是NonterminalExpressionTerminalExpression的实例的一个抽象语法树然后初始化上下文并调用解释操作.

a. 每一非终结符表达式节点定义相应子表达式的解释操作。而各终结符表达式的解释操作构成了递归的基础.

b. 每一节点的解释操作用上下文来存储和访问解释器的状态.


五. 说明


1. 易于改变和扩展文法因为每一个规则都被封装到一个类中.

2. 也易于实现文法,  定义抽象语法树中各个节点的类的实现大体类似.

3. 复杂的文法难以维护如果有1万个文法你需要定义1万个类这明显不好维护.

4. InterpreterComposite模式在实现上有许多相通的地方(就是有一个递归).

5. 创建抽象语法树 解释器模式并未解释如何创建一个抽象的语法树(就是并没有对给出的字符串进行分离出对应的文法).

(例如: 1+3-4,  Interpreter模式可以对这条表达式求值1+3-4中每一项的分离Interpreter并没有去分析.)

6. 定义解释操作并不一定要在表达式类中定义解释操作(Interpret函数中传递给专门的类去解析).

7. 可以使用Flyweight模式共享终结符终结节点通常不存储关于它们在抽象语法树中位置的信息在解释过程中任何它们所需要的上下文信息都由父节点传递给它们因此在共享的(内部的)状态和传入的(外部的)状态区分得很明确这就用到了Flyweight模式.


我的理解


1. 书中例子


expression ::= literal | alternation | sequence | repetition | '(' expression ')'

alternation ::= expression '|' expression

sequence ::= expression '&' expression

repetition ::= expression '*'

literal ::= 'a' | 'b' | 'c' | ... {'a' | 'b' | 'c' | ...}*

符号expression是开始符号, literal是定义简单字的终结符.

表达式raining & (dogs | cats) *的语法树是:


图2

假设 raining & (dogs | cats) *中 raining 值为true; dogs值为false; cats值为false, 那么表达式raining & (dogs | cats) *的值就是true & (false | false) 那就是false. Interpreter模式的作用就是能方便的求出给定语法规则的表达式的值(Interpreter模式不解析表达式或者说不对语法解析,  例如raining & (dogs | cats) *字符串中的raining 怎样提取出来的,  不是Interpreter模式做的)


2. 例如我定义一个加减法则


// 表达式

expression ::= literal | PlusSign | MinusSign | '(' expression ')'

// 加号

PlusSign ::= '+'

// 减号

MinusSign ::= '-'

// 终结符

literal ::= '0' | '1' | '2' | ... {'0' | '1' | '2' | ... }

表达式1 + (3 - 1)的语法树就是:

Expression >>>>>literal PlusSign (Expression)>>>>literal PlusSign (literal  MinusSign  literal )

表达式1 + 2 - (3 - 1)的语法树有两棵分别:

Expression >>>>>Expression MinusSign (Expression)>>>>literal PlusSign literal  MinusSign  (literal  MinusSign  literal )

Expression >>>>>literal PlusSign Expression>>>>literal PlusSign literal - (Expression)>>>literal PlusSign literal  MinusSign  (literal  MinusSign  literal )
很明显完全展开后它们是一样的(殊途同归而已)

3. 对语法树求值可以使用Interpreter模式.


相关模式


Composite模式抽象语法树是一个复合模式的实例.


原创粉丝点击