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

@(设计模式)[设计模式, 解释器模式, Interpreter]

  • 设计模式学习笔记解释器Interpreter模式

    • 基本介绍
    • 解释器案例
      • 类图
      • 实现代码
        • Node抽象类
        • ParseException类
        • ProgramNode类
        • CommandListNode类
        • CommandNode类
        • RepeatCommandNode类
        • PrimitiveCommandNode类
        • Context类
        • 测试类
        • 运行结果
    • 解释器模式中的角色
      • AbstractExpression抽象表达式
      • TerminalExpression终结符表达式
      • NonterminalExpression非终结符表达式
      • Context文脉上下文
      • Client请求者
      • 类图

基本介绍

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

解释器案例

类图

实现代码

Node抽象类

package com.pc.interpreter.example;/*** 节点类*/
public abstract class Node {/*** 解析** @param context 上下文* @throws ParseException 解析异常*/public abstract void parse(Context context) throws ParseException;
}

ParseException类

package com.pc.interpreter.example;/*** 解析异常类*/
public class ParseException extends Exception {public ParseException(String msg) {super(msg);}
}

ProgramNode类

package com.pc.interpreter.example;/*** 程序节点类* <program> ::= program <command list>*/
public class ProgramNode extends Node {/*** 命令列表节点*/private Node commandListNode;@Overridepublic void parse(Context context) throws ParseException {context.skipToken("program");commandListNode = new CommandListNode();commandListNode.parse(context);}@Overridepublic String toString() {return "[program " + commandListNode + "]";}
}

CommandListNode类

package com.pc.interpreter.example;import java.util.ArrayList;/*** 命令列表节点类* <command list> ::= <command>* end*/
public class CommandListNode extends Node {/*** 命令列表*/private ArrayList list = new ArrayList();@Overridepublic void parse(Context context) throws ParseException {while (true) {if (context.currentToken() == null) {throw new ParseException("Missing 'end'");} else if (context.currentToken().equals("end")) {context.skipToken("end");break;} else {Node commandNode = new CommandNode();commandNode.parse(context);list.add(commandNode);}}}@Overridepublic String toString() {return list.toString();}
}

CommandNode类

package com.pc.interpreter.example;/*** 命令节点类* <command> ::= <repeat command> | <primitive command>*/
public class CommandNode extends Node {/*** 节点*/private Node node;@Overridepublic void parse(Context context) throws ParseException {if (context.currentToken().equals("repeat")) {node = new RepeatCommandNode();node.parse(context);} else {node = new PrimitiveCommandNode();node.parse(context);}}@Overridepublic String toString() {return node.toString();}
}

RepeatCommandNode类

package com.pc.interpreter.example;/*** 重复命令节点类* <repeat command> ::= repeat <number> <command list>*/
public class RepeatCommandNode extends Node {/*** 重复次数*/private int number;/*** 命令列表节点*/private Node commandListNode;@Overridepublic void parse(Context context) throws ParseException {context.skipToken("repeat");number = context.currentNumber();context.nextToken();commandListNode = new CommandListNode();commandListNode.parse(context);}@Overridepublic String toString() {return "[repeat " + number + " " + commandListNode + "]";}
}

PrimitiveCommandNode类

package com.pc.interpreter.example;/*** 原始命令节点类* <primitive command> ::= go | right | left*/
public class PrimitiveCommandNode extends Node {/*** 名字*/private String name;@Overridepublic void parse(Context context) throws ParseException {name = context.currentToken();context.skipToken(name);if (!name.equals("go") && !name.equals("right") && !name.equals("left")) {throw new ParseException(name + " is undefined");}}@Overridepublic String toString() {return name;}
}

Context类

package com.pc.interpreter.example;import java.util.StringTokenizer;/*** 上下文类*/
public class Context {/*** 分词器*/private StringTokenizer tokenizer;/*** 当前符号*/private String currentToken;public Context(String text) {this.tokenizer = new StringTokenizer(text);this.nextToken();}/*** 返回下一个符号** @return 下一个符号*/public String nextToken() {if (tokenizer.hasMoreTokens()) {this.currentToken = this.tokenizer.nextToken();} else {this.currentToken = null;}return this.currentToken;}/*** 返回当前符号** @return 当前符号*/public String currentToken() {return this.currentToken;}/*** 跳过指定符号** @param token 指定符号* @throws ParseException 解析异常*/public void skipToken(String token) throws ParseException {if (!token.equals(this.currentToken)) {throw new ParseException("Warning: " + token + " is expected, but " + currentToken + " is found.");}this.nextToken();}/*** 解析数值** @return 数值* @throws ParseException 解析异常*/public int currentNumber() throws ParseException {int number = 0;try {number = Integer.parseInt(currentToken);} catch (NumberFormatException e) {throw new ParseException("Warning: " + e);}return number;}
}

测试类

package com.pc.interpreter.example.test;import com.pc.interpreter.example.Context;
import com.pc.interpreter.example.Node;
import com.pc.interpreter.example.ProgramNode;
import org.junit.Test;import java.io.BufferedReader;
import java.io.FileReader;/*** Interpreter Tester.** @author Switch* @version 1.0*/
public class InterpreterTest {/*** 测试解释器模式*/@Testpublic void testInterpreter() {try {BufferedReader reader = new BufferedReader(new FileReader(System.getProperty("user.dir")+ "/src/main/java/com/pc/interpreter/example/program.txt"));String text;while ((text = reader.readLine()) != null) {System.out.println("text = \"" + text + "\"");Node node = new ProgramNode();node.parse(new Context(text));System.out.println("node = " + node);}} catch (Exception e) {e.printStackTrace();}}
}

运行结果

text = "program end"
node = [program []]
text = "program go end"
node = [program [go]]
text = "program go right go right go right go right end"
node = [program [go, right, go, right, go, right, go, right]]
text = "program repeat 4 go right end end"
node = [program [[repeat 4 [go, right]]]]
text = "program repeat 4 repeat 3 go right go left end right end end"
node = [program [[repeat 4 [[repeat 3 [go, right, go, left]], right]]]]

解释器模式中的角色

AbstractExpression(抽象表达式)

AbstractExpression角色定义了语法树节点的共同接口(API)。在案例中,由Node类扮演此角色。在案例中,共同接口(API)的名字是parse,不过在类图中它的名字是interpreter

TerminalExpression(终结符表达式)

TerminalExpression角色对应BNF中的终结特表达式。在案例中,由PrimitiveCommandNode类扮演此角色。

NonterminalExpression(非终结符表达式)

NonterminalExpression角色对应BNF中的非终结符表达式。在案例中,由ProgramNode类、CommandNode类、RepeatCommandNode类和CommandListNode 类扮演此角色。

Context(文脉、上下文)

Context 角色为解释器进行语法解析提供了必要的信息。在案例中,由Context 类扮演此角色。

Client(请求者)

为了推导语法树, C li ent 角色会调用TerminalExpression 角色和Nonterm inalExpress i on 角色。在案例中,由Ma 工n 类扮演此角色。

类图

GitHub:DesignPatternStudy

——————参考《图解设计模式》

设计模式学习笔记——解释器(Interpreter)模式相关推荐

  1. 设计模式学习笔记——命令(Command)模式

    设计模式学习笔记--命令(Command)模式 @(设计模式)[设计模式, 命令模式, command] 设计模式学习笔记命令Command模式 基本介绍 命令案例 类图 实现代码 Command接口 ...

  2. 设计模式学习笔记——代理(Proxy)模式

    设计模式学习笔记--代理(Proxy)模式 @(设计模式)[设计模式, 代理模式, proxy] 设计模式学习笔记代理Proxy模式 基本介绍 代理案例 类图 实现代码 Printable接口 Pri ...

  3. 设计模式学习笔记——状态(State)模式框架

    设计模式学习笔记--状态(State)模式框架 @(设计模式)[设计模式, 状态模式, State] 设计模式学习笔记状态State模式框架 基本介绍 状态案例 类图 实现代码 State接口 Day ...

  4. 设计模式学习笔记——备忘录(Memento)模式

    设计模式学习笔记--备忘录(Memento)模式 @(设计模式)[设计模式, 备忘录模式, memento] 设计模式学习笔记备忘录Memento模式 基本介绍 备忘录案例 类图 实现代码 Memen ...

  5. 设计模式学习笔记——观察者(Observer)模式

    设计模式学习笔记--观察者(Observer)模式 @(设计模式)[设计模式, 观察者模式, Observer] 设计模式学习笔记观察者Observer模式 基本介绍 观察者案例 类图 实现代码 Ob ...

  6. 设计模式学习笔记——外观(Facade)模式

    设计模式学习笔记--外观(Facade)模式 @(设计模式)[设计模式, 外观模式, facade] 设计模式学习笔记外观Facade模式 基本介绍 外观案例 类图 实现代码 Database类 ma ...

  7. 设计模式学习笔记——访问者(Visitor)模式

    设计模式学习笔记--访问者(Visitor)模式 @(设计模式)[设计模式, 访问者模式, visitor] 设计模式学习笔记访问者Visitor模式 基本介绍 访问者案例 类图 实现代码 Visit ...

  8. 设计模式学习笔记——装饰(Decorator)模式

    设计模式学习笔记--装饰(Decorator)模式 @(设计模式)[设计模式, 装饰模式, decorator] 设计模式学习笔记装饰Decorator模式 基本介绍 装饰案例 类图 实现代码 Dis ...

  9. 设计模式学习笔记——组合(Composite)模式

    设计模式学习笔记--组合(Composite)模式 @(设计模式)[设计模式, 组合模式, composite] 设计模式学习笔记组合Composite模式 基本介绍 组合案例 类图 实现代码 Ent ...

最新文章

  1. Android开发实现QQ三方登录 标签: android开发qq三方登录
  2. 线性代数可以速成吗_广播/学习吉他速成靠谱吗?真的可以速成吗?
  3. 安装ORACLE RAC时,用到的一些小命令1.弹出CD,2:配置时间同步,3.查看磁盘信息UUID
  4. 收集一些优秀的DoNet开源项目
  5. android sd卡不可写,Android检查SD卡是否可读写
  6. 一个非科班大学生的四年,到秋招收获了腾讯和字节的offer
  7. 获取微信的access_tokey,处理json格式的数据
  8. 总结: 《jQuery基础教程》 1-4章
  9. “重命名”用“改名”更好
  10. 券商交易模式下的单产品多券商方案
  11. 使用 PyQt5 和 Echarts 打造股票数据看板
  12. 大工计算机英语考试,大工15春《专业英语(计算机英语)》在线测试123
  13. 深圳大学使用路由器登陆校园网,openwrt登陆drcom,d版教程
  14. 【雅思大作文考官范文】——第十六篇:climate change essay
  15. 深圳电视台小间距P2高清圆弧屏(弧形屏)是用软模组(软屏)拼成
  16. matlab直流电机初始转速,直流电机转速控制的matlab实验.doc
  17. 落单的数(Java)
  18. 用友金蝶 不同道路,殊途同归
  19. PKI基础知识(数字信封与数字签名过程,对称密钥与非对称密钥)
  20. 爬虫第四式:增量爬虫之爬取汽车之家数据

热门文章

  1. 微信小程序入门三:轮播图
  2. 【Python】Python库之数据可视化
  3. linux shell 读取文件脚本
  4. flutter bloc_如何使用BLoC模式处理Flutter中的状态
  5. heroku服务器_如何在Heroku上使用Express服务器部署React应用
  6. JavaScript变量作用域如何像多个级别的政府一样
  7. u8薪资管理_用友U8习题集
  8. 8个必备的Python GUI库
  9. Python打包文件为exe,PyInstaller应用
  10. Python编码风格指南