自定义语言的实现——解释器模式

上传人:wm****3 文档编号:41842739 上传时间:2018-05-31 格式:DOC 页数:23 大小:412.50KB
返回 下载 相关 举报
自定义语言的实现——解释器模式_第1页
第1页 / 共23页
自定义语言的实现——解释器模式_第2页
第2页 / 共23页
自定义语言的实现——解释器模式_第3页
第3页 / 共23页
自定义语言的实现——解释器模式_第4页
第4页 / 共23页
自定义语言的实现——解释器模式_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《自定义语言的实现——解释器模式》由会员分享,可在线阅读,更多相关《自定义语言的实现——解释器模式(23页珍藏版)》请在金锄头文库上搜索。

1、 自定义语言的实现自定义语言的实现解释器模式解释器模式http:/ 简单的语言来实现一些特定的操作,我们只要向计算机输入一个句子或文件, 它就能够按照预先定义的文法规则来对句子或文件进行解释,从而实现相应的 功能。例如提供一个简单的加法/减法解释器,只要输入一个加法/减法表达式, 它就能够计算出表达式结果,如图 18-1 所示,当输入字符串表达式为“1 + 2 + 3 4 + 1”时,将输出计算结果为 3。图图 18-1 加法加法/减法解释器示意图减法解释器示意图我们知道,像 C+、Java 和 C#等语言无法直接解释类似“1+ 2 + 3 4 + 1”这 样的字符串(如果直接作为数值表达式时

2、可以解释),我们必须自己定义一套文法规则来实现对这些语句的解释,即设计一个自定义语言。在实际 开发中,这些简单 的自定义语言可以基于现有的编程语言来设计,如果所基于 的编程语言是面向对象语言,此时可以使用解释器模式来实现自定义语言。18.118.1 机器人控制程序机器人控制程序Sunny 软件公司欲为某玩具公司开发一套机器人控制程序,在该机器人控制 程序中包含一些简单的英文控制指令,每一个指令对应一个表达式(expression), 该表达式可以是简单表达式也可以是复合表达式,每一个简单表达式由移动方 向(direction),移动方式(action)和移动距离(distance)三部分组成,

3、其中移动方向 包括上(up)、下(down)、左(left)、右(right);移动方式包括移动(move)和快速移 动(run);移动距离为一个正整数。两个表达式之间可以通过与(and)连接,形成 复合(composite)表达式。用户通过对图形化的设置界面进行操作可以创建一个机器人控制指令, 机器人在收到指令后将按照指令的设置进行移动,例如输入控制指令:up move 5,则“向上移动 5 个单位”;输入控制指令:down run 10 and left move 20, 则“向下快速移动 10 个单位再向左移动 20 个单位”。Sunny 软件公司开发人员决定自定义一个简单的语言来解释机

4、器人控制指令, 根据上述需求描述,用形式化语言来表示该简单语言的文法规则如下:expression := direction action distance | composite /表达式composite := expression and expression /复合表达式direction := up | down | left | right /移动方向action := move | run /移动方式distance := an integer /移动距离上述语言一共定义了五条文法规则,对应五个语言单位,这些语言单位 可以分为两类,一类为终结符(也称为终结符表达式),例如 dir

5、ection、action 和 distance,它们是语言的最小组成单位,不能再进行拆分;另一类为非终结符 (也称为非终结符表达式),例如 expression 和 composite,它们都是一个完整 的句子,包含一系列终结符或非终结符。我们根据上述规则定义出的语言可以构成很多语句,计算机程序将根据 这些语句进行某种操作。为了实现对语句的解释,可以使用解释器模式,在解 释器模式中每一 个文法规则都将对应一个类,扩展、改变文法以及增加新的文 法规则都很方便,下面就让我们正式进入解释器模式的学习,看看使用解释器 模式如何来实现对机器人 控制指令的处理。18.218.2 文法规则和抽象语法树文法

6、规则和抽象语法树解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表 示一个句子,以及如何解释这些句子。示一个句子,以及如何解释这些句子。在正式分析解释器模式结构之前,我们 先来学习如何表示一个语言的文法规则以及如何构造一棵抽象语法树。在前面所提到的加法/减法解释器中,每一个输入表达式,例如“1 + 2 + 3 4 + 1”,都包含了三个语言单位,可以使用如下文法规则来定义:expression := value | operationoperation := expression + expression | expre

7、ssion - expressionvalue := an integer /一个整数值该文法规则包含三条语句,第一条表示表达式的组成方式,其中 value 和 operation 是后面两个语言单位的定义,每一条语句所定义的字符串如 operation 和 value 称为语言构造成分或语言单位,符号“:=”表示“定义为” 的意思,其左边的语言单位通过右边来进行说明和定义,语言单位对应终结符 表达式和非终结符表达式。如本规则中的 operation 是非终结符表达式,它的组 成元素仍然可以是表达式,可以进一步分解,而 value 是终结符表达式,它的 组成元素是最基本的语言单位,不能再进行分

8、解。在文法规则定义中可以使用一些符号来表示不同的含义,如使用“|” 表示或,使用“”和“”表示组合,使用“*”表示出现 0 次或多次等,其中 使用频率最高的符号是表示“或”关系的“|”,如文法规则“boolValue := 0 | 1”表示终结符表达式 boolValue 的取值可以为 0 或者 1。除了使用文法规则来定义一个语言,在解释器模式中还可以通过一种称 之为抽象语法树抽象语法树(Abstract Syntax Tree, AST)的图形方式来直观地表示语言的构 成,每一棵抽象语法树对应一个语言实例,如加法/减法表达式语言中的语句“1+ 2 + 3 4 + 1”,可以通过如图 18-2

9、 所示抽象语法树来表示:图图 18-2 抽象语法树示意图抽象语法树示意图在该抽象语法树中,可以通过终结符表达式 value 和非终结符表达式 operation 组成复杂的语句,每个文法规则的语言实例都可以表示为一个抽象语每个文法规则的语言实例都可以表示为一个抽象语 法树法树,即每一条具体的语句都可以用类似图 18-2 所示的抽象语法树来表示,在在 图中终结符表达式类的实例作为树的叶子节点,而非终结符表达式类的实例作图中终结符表达式类的实例作为树的叶子节点,而非终结符表达式类的实例作 为非叶子节点,它们可以将终结符表达式类的实例以及包含终结符和非终结符为非叶子节点,它们可以将终结符表达式类的实

10、例以及包含终结符和非终结符 实例的子表达式作为其子节点实例的子表达式作为其子节点。抽象语法树描述了如何构成一个复杂的句子, 通过对抽象语法树的分析,可以识别出语言中的终结符类和非终结符类。18.318.3 解释器模式概述解释器模式概述解释器模式是一种使用频率相对较低但学习难度较大的设计模式,它用 于描述如何使用面向对象语言构成一个简单的语言解释器。在某些情况下,为 了更好地描述某 一些特定类型的问题,我们可以创建一种新的语言,这种语言 拥有自己的表达式和结构,即文法规则,这些问题的实例将对应为该语言中的 句子。此时,可以使用解 释器模式来设计这种新的语言。对解释器模式的学习 能够加深我们对面向

11、对象思想的理解,并且掌握编程语言中文法规则的解释过 程。解释器模式定义如下:解释器模式解释器模式(Interpreter Pattern):定义一个语言的文法,并且建立一个解释器:定义一个语言的文法,并且建立一个解释器 来解释该语言中的句子,这里的来解释该语言中的句子,这里的“语言语言”是指使用规定格式和语法的代码。解是指使用规定格式和语法的代码。解 释器模式是一种类行为型模式。释器模式是一种类行为型模式。由于表达式可分为终结符表达式和非终结符表达式,因此解释器模式的 结构与组合模式的结构有些类似,但在解释器模式中包含更多的组成元素,它 的结构如图 18-3 所示:图图 18-3 解释器模式结

12、构图解释器模式结构图在解释器模式结构图中包含如下几个角色: AbstractExpression(抽象表达式):在抽象表达式中声明了抽象的解释操作,它是所有终结符表达式和非终结符表达式的公共父类。 TerminalExpression(终结符表达式):终结符表达式是抽象表达式的子类,它实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例。通常在一个解释器模式中只有少数几个终结符表达 式类,它们的实例可以通过非终结符表达式组成较为复杂的句子。 NonterminalExpression(非终结符表达式):非终结符表达式也是抽象表达式的子类,它实现了文法中非终结符的解释

13、操作,由于在非终结符表达 式中可以包含终结符表达式,也可以继续包含非终结符表达式,因此其解释操 作一般通过递归的方式来完成。 Context(环境类):环境类又称为上下文类,它用于存储解释器之外的一些全局信息,通常它临时存储了需要解释的语句。在解释器模式中,每一种终结符和非终结符都有一个具体类与之对应, 正因为使用类来表示每一条文法规则,所以系统将具有较好的灵活性和可扩展 性。对于所有的终结符和非终结符,我们首先需要抽象出一个公共父类,即抽 象表达式类,其典型代码如下所示:abstract class AbstractExpression public abstract void interp

14、ret(Context ctx);终结符表达式和非终结符表达式类都是抽象表达式类的子类,对于终结 符表达式,其代码很简单,主要是对终结符元素的处理,其典型代码如下所示:class TerminalExpression extends AbstractExpression public void interpret(Context ctx) /终结符表达式的解释操作对于非终结符表达式,其代码相对比较复杂,因为可以通过非终结符将 表达式组合成更加复杂的结构,对于包含两个操作元素的非终结符表达式类, 其典型代码如下:class NonterminalExpression extends Abstra

15、ctExpression private AbstractExpression left;private AbstractExpression right;public NonterminalExpression(AbstractExpression left,AbstractExpression right) this.left=left;this.right=right;public void interpret(Context ctx) /递归调用每一个组成部分的递归调用每一个组成部分的 interpret()方法方法/在递归调用时指定组成部分的连接方式,即非终结符的功能在递归调用时指定组成部分的连接方式,即非终结符的功能 除了上述用于表示表达式的类以外,通常在解释器模式中还提供了一个 环境类 Context,用于存储一些全局信息,通常在 Context 中包含了一个 HashMap 或 ArrayList 等类型的集合对象(也可以直接由 HashMap 等集合类充 当环境类),存储一系列公共信息,如变量名与值的映射关系(key/value)等, 用于在进行具体的解释操作时从中获取相关信息。其典型代码片段如下:class Context private HashMap map = new HashMap();public void assi

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号