解释器模式(Interpreter Pattern)

发布时间 2023-04-01 12:19:31作者: ImreW

一、概念

解释器模式(Interpreter Pattern) 用于构造一个简单的语言解释器,将字符串按照自定义的方式解释执行 ,是一种不常用的设计模式

  • 除非从事底层开发自己需要去定义较为复杂的表达式,否则基本上不同这个设计模式

二、适用场景

(1)当一个语言需要解释执行,并可以将该语言中的句子表示为一个抽象语法树的时候,可以考虑使用解释器模式(如XML文档解释、正则表达式等领域)。

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

(3)一个语言的文法较为简单。

(4)当执行效率不是关键和主要关心的问题时可考虑解释器模式(注:高效的解释器通常不是通过直接解释抽象语法树来实现的,而是需要将它们转换成其他形式,使用解释器模式的执行效率并不高。)

三、参与者

解释器模式有以下4种角色

  1. 抽象解释器(Abstract Expression):一般会定义一个解释方法,具体如何解析会交由子类进行实现
  2. 终结符表达式(Terminal Expression):实现语法中与终结符有关的解释操作。语法中每一个终结符都有一个具体的终结符表达式与之相对应
    • 比如我们的R=M+N运算,M和N就是终结符,对应的解析M和N的解释器就是 "终结符表达式"
  3. 非终符结表达式(Nonterminal Expression):实现语法中与非终结符有关的解释操作。语法中的每一条规则都对应了一个非终结符表达式。非终结表达式一般是文法中的运算符或者关键字
    • 如上面公示:R=M+N中的“+”号 就是非终结符,解析“+”号的解释器就是一个 "非终结符表达式"
  4. 上下文环境(Context):包含解释器之外的全局信息。 存储各个解释器需要使用到的数据,或是公共功能。

四、代码例子

一个简单控制小车移动的例子

 该例子中的文法相对比较简单,语法如下所示:

/******************************************************************
 ** expression ::= direction action distance | composite //表达式
 ** composite ::= expression 'and' expression //复合表达式
 ** direction ::= 'up' | 'down' | 'left' | 'right' //移动方向
 ** action ::= 'move' //移动方式
 ** distance ::= an integer //移动距离
 ******************************************************************/

 

抽象解释器(Abstract Expression):AbstractExpression

终结符表达式(Terminal Expression):SentenceExpression

非终符结表达式(Nonterminal Expression):AndNode、DirectionExpression、ActionExpression、DistanceExpression

上下文环境(Context):Context

五、UML图

六、优缺点

(一)优点

(1)易于改变和扩展文法。

(2)每一条文法规则都可以表示为一个类,因此可以方便地实现一个简单的语言。

(3)实现文法较为容易。在抽象语法树中每一个表达式节点类的实现方式都是相似的,这些类的代码编写都不会特别复杂,还可以通过一些工具自动生成节点类代码。

(4)增加新的解释表达式较为方便。如果用户需要增加新的解释表达式只需要对应增加一个新的终结符表达式或非终结符表达式类,原有表达式类代码无须修改,符合“开闭原则”

(二)缺点

(1)对于复杂文法难以维护。在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,类的个数将会急剧增加,导致系统难以管理和维护,此时可以考虑使用语法分析程序等方式来取代解释器模式。

(2)执行效率较低。由于在解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时其速度很慢,而且代码的调试过程也比较麻烦。