首页 > 其他分享 >设计模式—解释器模式

设计模式—解释器模式

时间:2023-07-25 12:55:54浏览次数:28  
标签:解释器 right HashMap 模式 var 设计模式 Expression public left

解释器模式

解释器模式(Interpreter Pattern)是一种按照规定语法进行解析的方案,在现在项目中使 用较少,其定义如下:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language。

优点

解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改 相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。

缺点

  • 解释器模式会引起类膨胀。
  • 解释器模式采用递归调用方法。
  • 效率问题:解释器模式由于使用了大量的循环和递归,效率是一个不容忽视的问题,特别是一用于 解析复杂、冗长的语法时,效率是难以忍受的。

使用场景

  • 重复发生的问题可以使用解释器模式
  • 一个简单语法需要解释的场景

例子:模拟计算表达式

  • 抽象表达式
/**
 * 抽象表达式
 *
 * @author admin
 */
public abstract class Expression {
    /**
     * 解析公式和数值,其中var中的key值是公式中的参数,value值是具体的数字
     *
     * @param var 参数
     * @return 返回值
     */
    public abstract int interpreter(HashMap<String, Integer> var);
}
  • 变量解析器
import java.util.HashMap;

/**
 * 变量解析器
 *
 * @author admin
 */
public class VarExpression extends Expression {
    private String key;

    public VarExpression(String key) {
        this.key = key;
    }

    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return var.get(key);
    }
}
  • 抽象运算符号解析器
/**
 * 抽象运算符号解析器
 *
 * @author admin
 */
public abstract class SymbolExpression extends Expression {
    protected Expression left;
    protected Expression right;

    /**
     * 所有的解析公式都应只关心自己左右两个表达式的结果
     *
     * @param left  左侧表达式
     * @param right 右侧表达式
     */
    public SymbolExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
}
  • 加法解析器
import java.util.HashMap;

/**
 * 加法解析器
 *
 * @author admin
 */
public class AddExpression extends SymbolExpression {
    public AddExpression(Expression left, Expression right) {
        super(left, right);
    }

    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return super.left.interpreter(var) + super.right.interpreter(var);
    }
}
  • 减法解析器
import java.util.HashMap;

/**
 * 减法解析器
 *
 * @author admin
 */
public class SubExpression extends SymbolExpression {
    public SubExpression(Expression left, Expression right) {
        super(left, right);
    }

    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return super.left.interpreter(var) - super.right.interpreter(var);
    }
}
  • 解析器封装类
import java.util.HashMap;
import java.util.Stack;

/**
 * 解析器封装类
 *
 * @author admin
 */
public class Calculator {
    //定义表达式
    private Expression expression;

    //构造函数传参,并解析
    public Calculator(String expStr) {
        //定义一个栈,安排运算的先后顺序
        Stack<Expression> stack = new Stack<>();
        //表达式拆分为字符数组
        char[] charArray = expStr.toCharArray();
        //运算
        Expression left;
        Expression right;
        for (int i = 0; i < charArray.length; i++) {
            switch (charArray[i]) {
                case '+': //加法
                    //加法结果放到栈中
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new AddExpression(left, right));
                    break;
                case '-':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new SubExpression(left, right));
                    break;
                default: //公式中的变量
                    stack.push(new VarExpression(String.valueOf(charArray[i])));
            }
        }
        //把运算结果抛出来
        this.expression = stack.pop();
    }

    //开始运算
    public int run(HashMap<String, Integer> var) {
        return this.expression.interpreter(var);
    }
}
  • 客户端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

public class Client {
    //运行四则运算
    public static void main(String[] args) throws IOException {
        String expStr = getExpStr();
        //赋值
        HashMap<String, Integer> var = getValue(expStr);
        Calculator cal = new Calculator(expStr);
        System.out.println("运算结果为:" + expStr + "=" + cal.run(var));
    }

    //获得表达式
    public static String getExpStr() throws IOException {
        System.out.print("请输入表达式:");
        return (new BufferedReader(new InputStreamReader(System.in))).readLine();
    }

    //获得值映射
    public static HashMap<String, Integer> getValue(String exprStr) throws IOException {
        HashMap<String, Integer> map = new HashMap<>();
        //解析有几个参数要传递
        for (char ch : exprStr.toCharArray()) {
            if (ch != '+' && ch != '-') {
                //解决重复参数的问题
                if (!map.containsKey(String.valueOf(ch))) {
                    String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
                    map.put(String.valueOf(ch), Integer.valueOf(in));
                }
            }
        }
        return map;
    }
}

标签:解释器,right,HashMap,模式,var,设计模式,Expression,public,left
From: https://www.cnblogs.com/kouhao/p/17579626.html

相关文章

  • 设计模式—门面模式
    门面模式门面模式(FacadePattern)也叫做外观模式,是一种比较常用的封装模式。要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。优点减少系统的相互依赖;提高了灵活性;提高安全性。缺点是不符合......
  • 设计模式—原型模式
    原型模式原型模式(PrototypePattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。优点原型模式是在内存二进制流的拷贝,要比直接new一个对象性......
  • 设计模式—工厂模式
    目录简单工厂模式类图案例分析工厂方法模式优点类图案例分析抽象工厂模式优点缺点使用场景注意事项类图案例分析工厂模式分为简单工厂模式,工厂方法模式,抽象工厂模式。简单工厂模式简单工厂模式的核心是定义一个创建对象的接口,将对象的创建和本身的业务逻辑分离,降低系统的耦合度......
  • vs c#判断程序是否调试模式,开发模式,发布模式,Debug模式,Release模式
    转发自:https://blog.csdn.net/qq_37664403/article/details/1187471951.Debug模式,Release模式#ifDEBUGConsole.WriteLine(“Debug模式”);#elseConsole.WriteLine(“Release模式”);#endif此方法适合习惯好的程序员,但是对我来说不怎么习惯使用,因为调试个代码,和不在调试情况下运......
  • Java开发笔记之mac的intellij idea在debug模式下卡住的问题
    0x00问题描述mac的Intellijidea在debug模式下放行时,程序会卡住无响应;即使在已经放行的情况下,后续代码也不运行,console内只显示Theapplicationisrunning或者等了很久程序才开始后续的运行。 0x01解决方案修改host中的配置。通过以下命令,打开hosts的编辑页面。sudovi......
  • 非关语言: 设计模式
    http://www.riabook.cn/doc/designpattern/非关语言:设计模式程式设计是思维具体化的一种方式,是思考如何解决问题的过程,设计模式是在解决问题的过程中,一些良好思路的经验集成,最早讲设计模式,人们总会提到Gof 的著作,它最早将经典的23种模式集合在一起说明,对后期学习程式设计,尤......
  • IMU模式下DML语句所产生的REDO RECORD格式解读
    总结:IMU模式下DML语句所产生的REDORECORD格式,是先有操作的changerector,再有向向UNDO段头的事务表写事务信息的changerector,再提交操作的changerector后,才进行把数据修改前值放到UNDO的changerector。注意:实验中INSERT和DELETE是先后做的,UPDATE操作是......
  • 深入解析Oracle IMU模式下的REDO格式
    1.什么是IMU?IMU的主要作用是什么,也就是说为了解决什么问题?IMU--->InMemoryUndo,10g新特性,数据库会在sharedpool开辟独立的内存区域用于存储Undo信息,每个新事务都会分配一个IMUbuffer(私有的),一个buffer里有很多node,一个node相当于一个block(回滚块)。IMU特性:IMU顾名思义就是在内......
  • 非IMU模式下DML语句产生的REDO日志内容格式解读
    实验内容:非IMU模式下DML语句产生的REDO日志内容格式解读,数据库版本:11.2.0.4最详细的解读是UPDATE的。实验环境准备11G中默认是开启IMU特性的,做此实验需要关闭此特性。altersystemset"_in_memory_undo"=false;altersystemset"_in_memory_undo"=true......
  • OLAP系列之分析型数据库clickhouse主从副本模式(三)
    一、测试单分片,单副本或多副本模式#1.停止集群systemctlstopclickhouse-server#修改配置文件vim/etc/clickhouse-server/config.d/metrika.xml<remote_servers><clickhouse_cluster_3shards_1replicas><!--1个分片,1个副本--><sh......