zoukankan      html  css  js  c++  java
  • 解释器模式(Interpreter、Context、Expression)

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

    解释器模式的定义是一种按照规定语法进行解析的方案,在现在项目中使用的比较少,其定义如下:
    Given a language, define a representation for its grammar along with an interpreter that uses the
    representation to interpret sentences in the language.
    给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表达式来解释语言中的句子。

    解释器角色:
    1.AbstractExpression抽象解释器:具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和
    NonterminalExpression
    2.TerminalExpression终结符表达式:实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结
    表达式,但有多个实例,对应不同的终结符。
    3.NonterminalExpression非终结符表达式:文法中的每条规则对应于一个非终结表达式,非终结符表达式根据逻辑的
    复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式
    4.Context环境角色

     
     1 //抽象表达式
     2 /*抽象表达式是生产语法集合(也叫语法树)的关键,每个语法集合完成指定语法解析任务,它是通过递归调用的方式,最终
     3 由最小的语法单元进行解析完成*/
     4 public abstract class Expression{
     5     //每个表达式必须有一个解析任务
     6     public abstract Object interpreter(Context context);
     7 }
     8  
     9 //终结符表达式  主要是处理场景元素和数据的转换 如:a+b+c中的"a""b""c"
    10 public class TerminalExpression extends Expression{
    11     //通常终结符表达式只有一个,但是有多个对象
    12     public Object interpreter(Context context){
    13         return null;
    14     }
    15 }
    16  
    17 //非终结符表达式
    18 /*
    19     每个非终结符表达式都代表一个文法规则,并且每个文法规则都只关心自己周边的文法规则结果(注意是结果),因此
    20     这就产生了每个终结符表达式调用自己周边的非终结符表达式,然后最终,最小的文法规则就是终结符表达式,终
    21     结符表达式的概念就是如此,不能在参与比自己更小的文法运算了
    22 */
    23 public class NonterminalExpression extends Expression{
    24     //每个非终结符表达式都会对其他表达式产生依赖
    25     public NonterminalExpression(Expression... expression){
    26     }
    27      
    28     public Object interpreter(Context context){
    29         //进行文法处理
    30         return null;
    31     }
    32 }
    33  
    34 //场景类
    35 public class Client{
    36     public static void main(String[] args){
    37         Context context=new Context();
    38         //通常一个语法容器,容纳一个具体的表达式,通常为ListArray,LinkedList,Stack等类型
    39         Stack<Expression> stack=null;
    40         for(;;){
    41             //进行语法判断,并产生递归调用
    42         }
    43         //产生一个完整的语法树,由各个具体的语法分析进行解析
    44         Expression expression=stack.pop();
    45         //具体元素进入场景
    46         expression.interpreter(context);
    47     }
    48 }

    解析器模式的优点:
    解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就
    可以了,若扩展语法,则只要增加非终结符类就可以了
    缺点:
    1.解释器模式会引发类膨胀:每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的
    类文件,为维护带来了非常多的麻烦。
    2.解释器模式采用递归调用方法:每个非终结符表达式只关心与自己有关的表达式,每个表达式需要知道最终的
    结果,必须一层一层的剥茧,无论是面向过程的语言还是面向对象的语言,递归都是在必要条件下是使用的,它导致
    调试非常复杂
    3.效率问题:解释器模式由于使用了大量的循环和递归,效率是一个不容忽视的问题
    解释器模式使用的场景
    1.重复发生的问题可以使用解释器模式
    2.一个简单语法需要解释的场景

    注意事项
    尽量不要再重要的模块中使用解释器模式,否则维护会一个很大的问题。在项目中可以使用shell,jRuby,Groovy
    等脚本语言来代替解释器模式,弥补Java编译型语言的不足。

    常用的解释器模式工具包:Expression4J,MESP(Math Expression String parser),Jep等开源的解析工具包

  • 相关阅读:
    CSAPP DataLab
    《计算机网络自顶向下》第二章应用层,笔记总结
    计算机网络自顶向下第二章套接字编程作业
    第二章---信息的表示与处理
    python界面使用gbk编码
    python修改获取xlsx数据
    刚安装了ftp之后无法使用root访问,服务器发回了不可路由的地址。使用服务器地址代替。
    ssh_exchange_identification: read: Connection reset
    <七>对于之前的一些遗漏的地方的补充
    (六)单例模式与多线程时的安全问题以及解决办法
  • 原文地址:https://www.cnblogs.com/the-wang/p/7323997.html
Copyright © 2011-2022 走看看