设计模式之解释器模式
2016-03-11 13:51
411 查看
解释器模式(interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
如果一种特定类型的问题发生的概率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
AbstractExpression(抽象表达式),声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
TerminalExpression(终结符表达式),实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口,主要是一个interpret()方法。文法中每一个终结符都有一个具体终结表达式与之对应。
NonterminalExpression(非终结符表达式),为文法中的非终结符实现解释操作。对文法中每一条规则R1、R2...Rn都需要一个具体的非终结符表达式类。通过实现抽象表达式的interpret()方法实现解释操作。
Context,包含解释器之外的一些全局信息。
调用,构建表示该文法定义的语言中一个特定的句子的抽象语法树。调用解释操作。
输出结果:
当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。
容易地改变和扩展文法,因为该模式使用类来表示文法规则,你可使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类都易于直接编写。
解释器模式的不足:为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。建议当文法非常复杂时,使用其他的技术如语法分析程序或编译器生成器来处理。
密码解释器实现,!@#¥分别代表1234,+表示结束符。
输出结果:翻译结果:2341
如果一种特定类型的问题发生的概率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
AbstractExpression(抽象表达式),声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
public abstract class AbstractExpression { public abstract void interpret(Context context); }
TerminalExpression(终结符表达式),实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口,主要是一个interpret()方法。文法中每一个终结符都有一个具体终结表达式与之对应。
public class TerminalExpression extends AbstractExpression { @Override public void interpret(Context context) { System.out.println("终结表达式解释器"); } }
NonterminalExpression(非终结符表达式),为文法中的非终结符实现解释操作。对文法中每一条规则R1、R2...Rn都需要一个具体的非终结符表达式类。通过实现抽象表达式的interpret()方法实现解释操作。
public class NonterminalExpression extends AbstractExpression { @Override public void interpret(Context context) { System.out.println("非终结表达式解释器"); } }
Context,包含解释器之外的一些全局信息。
public class Context { private String mInput; private String mOutput; public void setInput(String input) { mInput = input; } public String getInput() { return mInput; } public void setOutput(String output) { mOutput = output; } public String getOutput() { return mOutput; } }
调用,构建表示该文法定义的语言中一个特定的句子的抽象语法树。调用解释操作。
Context context = new Context(); List<AbstractExpression> list = new ArrayList<AbstractExpression>(); list.add(new TerminalExpression()); list.add(new NonterminalExpression()); list.add(new TerminalExpression()); for (AbstractExpression item : list) { item.interpret(context); }
输出结果:
终结表达式解释器 非终结表达式解释器 终结表达式解释器
当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。
容易地改变和扩展文法,因为该模式使用类来表示文法规则,你可使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类都易于直接编写。
解释器模式的不足:为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。建议当文法非常复杂时,使用其他的技术如语法分析程序或编译器生成器来处理。
密码解释器实现,!@#¥分别代表1234,+表示结束符。
public abstract class AbstExpression { public abstract String excute(String s); }
public class TermExpression extends AbstExpression { @Override public String excute(String s) { String result = ""; if (s.equals("+")) { result = "."; } return result; } }
public class NontermExpression extends AbstExpression{ @Override public String excute(String s) { String result = ""; if (s.equals("!")) { result = "1"; } else if (s.equals("@")) { result = "2"; } else if (s.equals("#")) { result = "3"; } else if (s.equals("$")) { result = "4"; } return result; } }
public class InterpreterContext { private String mInput; public void setInput(String input) { mInput = input; } public String getResult() { String result = ""; int length = mInput.length(); if (length != 0) { AbstExpression expression = null; String str = null; for (int i = 0; i < length; i++) { str = mInput.substring(i, i + 1); if (str.equals("!") || str.equals("@") || str.equals("#") || str.equals("%")) { expression = new NontermExpression(); } else if (str.equals("+")) { expression = new TermExpression(); } result += expression.excute(str); } } System.out.println("翻译结果:" + result); return result; } }调用:
InterpreterContext interpreterContext = new InterpreterContext(); interpreterContext.setInput("@#$!+"); interpreterContext.getResult();
输出结果:翻译结果:2341
相关文章推荐
- 【一起学AngularJS】第七章、XHRs和依赖注入
- JS验证手机号码格式
- 基于CentOS6.5环境之下的LNMP之编译安装PHP5.5.30
- OC4J_DBConsole_test_orcl not found.
- Activiti支持直接部署扩展名为bpmn的流程文件
- PullableListView.canPullDown(PullableListView.java:33)----BUG
- Spring @Autowired,@Resource,@Required注解的用法和作用
- 为企业产品把好脉、开好方、下好药——老吴说产品
- cgroups2 数据结构设计
- LeetCode Palindrome Permutation II
- 电脑四则运算出题
- C++ 命名空间
- linux 下 rm 改为移动资料到回收站
- 1941: [Sdoi2010]Hide and Seek|K-D Tree
- 如何使用Signavio打包Activiti Modeler
- oracle表查询速度极慢的处理过程记录一下
- 动态更换view类的背景----StateListDrawable的应用
- 退出游戏行业去考研,可否?
- ORACLE创建序列
- 树状数组正确性的证明、、、