设计模式(第二十三式:解释器模式)
时间:2019-07-04
本文章向大家介绍设计模式(第二十三式:解释器模式),主要包括设计模式(第二十三式:解释器模式)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
概念:
解释器模式:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. 给定一门语言,定义他的文法的表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。这个其实就从根本上解释了java的运行原理。java我们通常说即使编译语言又是解释语言。这里就是解释语言就笨都是这么干的。
实现:
定义指令串
public class Directive { private Integer index = 0; private String [] commands; private String currentCommand; public Directive(String directive){ commands = directive.split(" "); nextCommand(); } public String nextCommand() { if(index < commands.length){ currentCommand = commands[index++]; }else { currentCommand = null; } return currentCommand; } public String getCurrentCommand(){ return currentCommand; } public void skipCurrentCommand(String command){ if(!command.equalsIgnoreCase(currentCommand)){ System.err.println("错误提示:"+command+"解析错误"); } nextCommand(); } public Integer getCurrentNum(String command){ try{ return Integer.parseInt(command); }catch (EnumConstantNotPresentException e){ System.err.println("错误提示:"+command+"不是数字"); } return null; } }
抽象指令关键字
public abstract class AbstractKey { public abstract void interpreter(Directive directive); public abstract void execute(); }
命令关键字
public class CommandKey extends AbstractKey { private AbstractKey node; @Override public void interpreter(Directive directive) { if (directive.getCurrentCommand().equalsIgnoreCase("loop")) { node = new LoopKey(); node.interpreter(directive); } else { node = new EndKey(); node.interpreter(directive); } } @Override public void execute() { node.execute(); } }
表达式关键字
public class ExpressionKey extends AbstractKey { private List<AbstractKey> list = new ArrayList<>(); @Override public void interpreter(Directive directive) { while (true) { if (directive.getCurrentCommand() == null) break; else if (directive.getCurrentCommand().equalsIgnoreCase("end")) { directive.skipCurrentCommand(directive.getCurrentCommand()); break; } else { AbstractKey expression = new CommandKey(); expression.interpreter(directive); list.add(expression); } } } @Override public void execute() { list.forEach(item -> { item.execute(); }); } }
循环关键字
public class LoopKey extends AbstractKey { private int number; private AbstractKey commandNode; @Override public void interpreter(Directive directive) { directive.skipCurrentCommand("LOOP"); number = directive.getCurrentNum(directive.getCurrentCommand()); directive.nextCommand(); commandNode = new ExpressionKey(); commandNode.interpreter(directive); } @Override public void execute() { for (int i = 0; i < number; i++) { commandNode.execute(); } } }
结束关键字
public class EndKey extends AbstractKey { private String name; private String text; @Override public void interpreter(Directive directive) { name = directive.getCurrentCommand(); directive.skipCurrentCommand(name); if (!name.equalsIgnoreCase("PRINT") && !name.equalsIgnoreCase("BREAK") && !name.equalsIgnoreCase("SPACE")) { System.out.println("非法指令"); } if (name.equalsIgnoreCase("PRINT")) { text = directive.getCurrentCommand(); directive.nextCommand(); } } @Override public void execute() { if (name.equalsIgnoreCase("PRINT")) System.out.print(text); else if (name.equalsIgnoreCase("SPACE")) System.out.print(" "); else if (name.equalsIgnoreCase("BREAK")) System.out.print("\r\n"); } }
测试及结果:
public class InterpreterTest {
@Test public void interpretertest(){ String directiveStr = "LOOP 2 PRINT good SPACE END PRINT study BREAK LOOP 2 PRINT day SPACE END PRINT up"; Directive directive = new Directive(directiveStr); AbstractKey node = new ExpressionKey(); node.interpreter(directive); System.out.println("原指令:"+directiveStr); System.out.println("解析后:"); node.execute(); } }
原指令:LOOP 2 PRINT good SPACE END PRINT study BREAK LOOP 2 PRINT day SPACE END PRINT up
解析后:
good good study
day day up
分析:
1.可以写简单的语法工具,ide更开发工具都有用到。
2.创造新的结束语言必要的一种设计模式。
3.平时基本很少用到,就不扯一些书上空洞的东西了,主要在于理解这种设计模式的思路和对解释型语言的运行。
原文地址:https://www.cnblogs.com/ben-mario/p/11134137.html
- Python Tips, Tricks, and Hacks
- 英特尔放出Linux微代码以修复Meltdown和Spectre漏洞
- python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域
- Linux SSH密码暴力破解技术及攻防实战
- 西部数据NAS设备被曝存在硬编码后门和未授权文件上传高危漏洞
- Hive & Performance 学习笔记
- 任意用户密码重置(一):重置凭证泄漏
- linux 系统监控、诊断工具之 top 详解
- 一个二进制POC的诞生之旅CVE-2018-0802
- 远程RPC溢出EXP编写实战之MS06-040
- 浮点数加法引发的问题:浮点数的二进制表示
- 新手科普 | MySQL手工注入之基本注入流程
- linux 系统监控、诊断工具之 lsof 用法简介
- 关于 SimpleDateFormat 的非线程安全问题及其解决方案
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Spring 中根据环境切换配置 @Profile
- Spring 中的属性赋值
- Spring 中控制 Bean 生命周期的几种方式及 BeanPostProcessor 执行原理
- Spring 中的 @Import 注解及向容器中添加 Bean 的几种方式
- Spring 注解开发之 @Conditional
- JDBC 技术应用实践:网上书城后台管理系统
- 思科模拟器:路由器基本配置
- 思科模拟器:实验五——高级路由实验
- 从零开始重新认识 SpringMVC
- 字节跳动Android实习面试凉凉经,两轮面试我被完虐了...
- 高效、简单、方便管理与维护的开源运维工单系统
- python数据库入门编程。
- EasyExcel导出自定义合并单元格策略
- CMake学习笔记
- 性能分析(2)- 应用程序 CPU 使用率过高案例