设计模式学习笔记——解释器(Interpreter)模式
设计模式学习笔记——解释器(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)模式相关推荐
- 设计模式学习笔记——命令(Command)模式
设计模式学习笔记--命令(Command)模式 @(设计模式)[设计模式, 命令模式, command] 设计模式学习笔记命令Command模式 基本介绍 命令案例 类图 实现代码 Command接口 ...
- 设计模式学习笔记——代理(Proxy)模式
设计模式学习笔记--代理(Proxy)模式 @(设计模式)[设计模式, 代理模式, proxy] 设计模式学习笔记代理Proxy模式 基本介绍 代理案例 类图 实现代码 Printable接口 Pri ...
- 设计模式学习笔记——状态(State)模式框架
设计模式学习笔记--状态(State)模式框架 @(设计模式)[设计模式, 状态模式, State] 设计模式学习笔记状态State模式框架 基本介绍 状态案例 类图 实现代码 State接口 Day ...
- 设计模式学习笔记——备忘录(Memento)模式
设计模式学习笔记--备忘录(Memento)模式 @(设计模式)[设计模式, 备忘录模式, memento] 设计模式学习笔记备忘录Memento模式 基本介绍 备忘录案例 类图 实现代码 Memen ...
- 设计模式学习笔记——观察者(Observer)模式
设计模式学习笔记--观察者(Observer)模式 @(设计模式)[设计模式, 观察者模式, Observer] 设计模式学习笔记观察者Observer模式 基本介绍 观察者案例 类图 实现代码 Ob ...
- 设计模式学习笔记——外观(Facade)模式
设计模式学习笔记--外观(Facade)模式 @(设计模式)[设计模式, 外观模式, facade] 设计模式学习笔记外观Facade模式 基本介绍 外观案例 类图 实现代码 Database类 ma ...
- 设计模式学习笔记——访问者(Visitor)模式
设计模式学习笔记--访问者(Visitor)模式 @(设计模式)[设计模式, 访问者模式, visitor] 设计模式学习笔记访问者Visitor模式 基本介绍 访问者案例 类图 实现代码 Visit ...
- 设计模式学习笔记——装饰(Decorator)模式
设计模式学习笔记--装饰(Decorator)模式 @(设计模式)[设计模式, 装饰模式, decorator] 设计模式学习笔记装饰Decorator模式 基本介绍 装饰案例 类图 实现代码 Dis ...
- 设计模式学习笔记——组合(Composite)模式
设计模式学习笔记--组合(Composite)模式 @(设计模式)[设计模式, 组合模式, composite] 设计模式学习笔记组合Composite模式 基本介绍 组合案例 类图 实现代码 Ent ...
最新文章
- Android开发实现QQ三方登录 标签: android开发qq三方登录
- 线性代数可以速成吗_广播/学习吉他速成靠谱吗?真的可以速成吗?
- 安装ORACLE RAC时,用到的一些小命令1.弹出CD,2:配置时间同步,3.查看磁盘信息UUID
- 收集一些优秀的DoNet开源项目
- android sd卡不可写,Android检查SD卡是否可读写
- 一个非科班大学生的四年,到秋招收获了腾讯和字节的offer
- 获取微信的access_tokey,处理json格式的数据
- 总结: 《jQuery基础教程》 1-4章
- “重命名”用“改名”更好
- 券商交易模式下的单产品多券商方案
- 使用 PyQt5 和 Echarts 打造股票数据看板
- 大工计算机英语考试,大工15春《专业英语(计算机英语)》在线测试123
- 深圳大学使用路由器登陆校园网,openwrt登陆drcom,d版教程
- 【雅思大作文考官范文】——第十六篇:climate change essay
- 深圳电视台小间距P2高清圆弧屏(弧形屏)是用软模组(软屏)拼成
- matlab直流电机初始转速,直流电机转速控制的matlab实验.doc
- 落单的数(Java)
- 用友金蝶 不同道路,殊途同归
- PKI基础知识(数字信封与数字签名过程,对称密钥与非对称密钥)
- 爬虫第四式:增量爬虫之爬取汽车之家数据