解释器模式(interpreter)java
定义:给定一种语言,定义他的方法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
git
类型:形为型模式 github
顺口溜:中访策备迭 观模命状职解sql
package com.amosli.dp.interpreter; public class Context { private String input; private String output; public String getInput() { return input; } public void setInput(String input) { this.input = input; } public String getOutput() { return output; } public void setOutput(String output) { this.output = output; } } package com.amosli.dp.interpreter; public abstract class AbstractExpression { public abstract void interpreter(Context context); } package com.amosli.dp.interpreter; public class NonTerminalExpression extends AbstractExpression { @Override public void interpreter(Context context) { System.out.println("this is NonTerminalExpression !"); } } package com.amosli.dp.interpreter; public class TerminalExpression extends AbstractExpression { @Override public void interpreter(Context context) { System.out.println("this is terminal expression!!!"); } } package com.amosli.dp.interpreter; import java.util.ArrayList; import java.util.List; public class Client { public static void main(String[] args) { Context context = new Context(); List<AbstractExpression> expressions = new ArrayList<AbstractExpression>(); expressions.add(new TerminalExpression()); expressions.add(new NonTerminalExpression()); expressions.add(new TerminalExpression()); for (AbstractExpression abstractExpression : expressions) { abstractExpression.interpreter(context); } } }
抽象解释器:声明一个全部具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操做。具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释器NonterminalExpression完成。express
终结符表达式:实现与文法中的元素相关联的解释操做,一般一个解释器模式中只有一个终结符表达式,但有多个实例,对应不一样的终结符。终结符一半是文法中的运算单元,好比有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。 ide
非终结符表达式:文法中的每条规则对应于一个非终结符表达式,非终结符表达式通常是文法中的运算符或者其余关键字,好比公式R=R1+R2中,+就是非终结符,解析+的解释器就是一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增长,原则上每一个文法规则都对应一个非终结符表达式。工具
环境角色:这个角色的任务通常是用来存放文法中各个终结符所对应的具体值,好比R=R1+R2,咱们给R1赋值100,给R2赋值200。这些信息须要存放到环境角色中,不少状况下咱们使用Map来充当环境角色就足够了。this
解释器是一个简单的语法分析工具,它最显著的优势就是扩展性,修改语法规则只须要修改相应的非终结符就能够了,若扩展语法,只须要增长非终结符类就能够了。spa
1)维护成本高code
解释器模式会引发类的膨胀,每一个语法都须要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来很是多的麻烦。
2)过于复杂时效率低
同时,因为采用递归调用方法,每一个非终结符表达式只关心与本身相关的表达式,每一个表达式须要知道最终的结果,必须经过递归方式,不管是面向对象的语言仍是面向过程的语言,递归都是一个不推荐的方式。因为使用了大量的循环和递归,效率是一个不容忽视的问题。特别是用于解释一个解析复杂、冗长的语法时,效率是难以忍受的。
本系列文章源码地址,https://github.com/amosli/dp 欢迎Fork & Star !!