03-JAVA设计模式-解析器模式

news2024/11/23 11:42:46

解释器模式

什么是解析器模式

在Java中,解释器模式(Interpreter Pattern)是一种行为设计模式,它给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。解释器模式主要用于处理包含特定语法规则的简单语言,如数学表达式、SQL语句、配置文件等。

解释器模式主要由以下角色组成:

  • 抽象表达式(Abstract Expression): 声明一个解释操作的接口,这个接口叫做解释操作。
  • 终结符表达式(Terminal Expression): 实现抽象表达式接口,该接口表示处理解释器语法中出现的终结符,终结符是语法中不可再分的最小单位。
  • 非终结符表达式(Nonterminal Expression): 同样实现抽象表达式接口,该接口表示处理解释器语法中出现的非终结符,非终结符是语法中的短语或句子,一般由终结符构成。
  • 环境角色(Context): 包含解释器之外的全局信息,一般是用来存储有关被解释句子的信息,如符号表的值等。
  • 客户端(Client): 构建(或给定)表示该文法的抽象语法树,并调用解释器的解释方法来执行程序。

注意:

解析器模式是一种不常用的设计模式

用于描述如何构成已个简单的语言解释器,主要用于使用面相对象语言开发编译器和解释器设计

当我们需要开发一种新的语言是,可以考虑使用

实际开发中尽量不要使用解释器模式,后期维护忽悠很大的麻烦,在项目中,可以使用Jruby,Groovy,java的js引擎来替代解释器的作用,弥补java语言的不足

案例

实现通过输入字符串10+30-25计算得到最终的结果

UML

在这里插入图片描述

实现步骤:

  • 定义解释接口及返回值Expression
  • 创建具体的表达式-数字NumberExpression
  • 创建具体的表达式-符号OperatorExpression
  • 创建具体的表达式-加法AddExpression
  • 创建具体的表达式-减法SubtractionExpression
  • 创建解析类ExpressionParser,实现表达式解析,且用队列存储解析后的表达式,提供interpret()方法执行表达式

实现代码

Expression.java

// 抽象表达式接口
public interface Expression {
    // 定义解释接口及返回值
    int interpret();
}

NumberExpression.java

// 具体的表达式-数字
public class NumberExpression implements Expression{
    // 定义接收值
    private Integer value;
    public NumberExpression(Integer value) {
        this.value = value;
    }
    @Override
    public int interpret() {
        return value;
    }
}

OperatorExpression.java

// 具体的表达式-符号
public class OperatorExpression implements Expression{
    // 定义接收值
    private char value;
    public OperatorExpression(char value) {
        this.value = value;
    }
    @Override
    public int interpret() {
        return value;
    }
}

AddExpression.java

// 具体的表达式-加法
public class AddExpression implements Expression{
    // 解析器左侧表达式
    private Expression left;
    // 解析器右侧表达式
    private Expression right;
    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
    @Override
    public int interpret() {
        return left.interpret() + right.interpret();
    }
}

Expression.java

// 具体的表达式-减法
public class SubtractionExpression implements Expression{
    // 解析器左侧表达式
    private Expression left;
    // 解析器右侧表达式
    private Expression right;
    public SubtractionExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
    @Override
    public int interpret() {
        return left.interpret() - right.interpret();
    }
}

ExpressionParser.java

import java.util.ArrayDeque;
import java.util.Deque;

// 解析器类
public class ExpressionParser{
    private String expression;
    private int index = 0;
    private Deque<Expression> queue = new ArrayDeque<Expression>();

    public ExpressionParser(String expression) {
        this.expression = expression;
        parse();
    }

    // 解析表达式
    public void parse(){
        // 判断是否连续数字
        boolean markDigit = false;
        // 判断是否连续运算符
        boolean markOperation = false;
        while (index < expression.length()){
            char c = expression.charAt(index);
            // 字符判断
            if(Character.isDigit(c) && !markDigit){
                markDigit = true;
                markOperation = false;
                parseNumber();
                continue;
            }
            else if((c == '+' || c == '-') && !markOperation){
                markDigit = false;
                markOperation = true;
                parseOperation();
            } else {
                throw new RuntimeException("输入字符错误: " + c);
            }
            index++;
        }
    }

    // 解析数字
    private void parseNumber() {
        StringBuilder sb = new StringBuilder();
        while (index < expression.length() && Character.isDigit(expression.charAt(index))) {
            sb.append(expression.charAt(index));
            index++;
        }
        int number = Integer.parseInt(sb.toString());
        queue.offer(new NumberExpression(number));
    }

    // 解析符号
    private void parseOperation() {
        queue.offer(new OperatorExpression(expression.charAt(index)));
    }

    // 计算
    public int interpret() {
        Expression result = null;
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            Expression pop = queue.poll();
            if(result == null){
                result = pop;
            }
            else if (pop instanceof OperatorExpression &&  pop.interpret() == '+') {
                result = new AddExpression(result, queue.poll());
                i++;
            }
            else if (pop instanceof OperatorExpression &&  pop.interpret() == '-') {
                result = new SubtractionExpression(result, queue.poll());
                i++;
            }
            else {
                throw new RuntimeException("表达式异常");
            }
        }
        return result.interpret();
    }
}

TestClient.java

// 测试
public class TestClient {
    public static void main(String[] args) {
        String expression = "10+30-25";
        ExpressionParser parser = new ExpressionParser(expression);
        System.out.println("Result: " + parser.interpret());
    }
}

执行结果:

在这里插入图片描述

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1633453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

unity3d使用3D WebView播放网页中的视频

Unity2021.3.35f1&#xff0c;硬件ESP32-Cam&#xff0c;3D WebView插件 1.新建工程&#xff0c;导入3D WebView for Winfows和3D WebView for Android 2.打开场景Assets\Vuplex\WebView\Demos\Scenes\2_CanvasWebViewDemo 3.修改Canvas的Render Mode为Screen Space-Camera&am…

30秒出服装设计稿,森马用Serverless+AIGC 整“新活”!

“创新项目如何去赋能我们的业务&#xff0c;这件事情在森马很重要。阿里云函数计算帮我们屏蔽掉了想把AI落地到实际业务场景中 GPU 算力资源储备、采购成本、技术门槛等很多难题&#xff0c;从而迅速做出决策&#xff0c;快人一步站在正确的起点&#xff0c;体验新技术对整个服…

『春招实习』2023年3月春招实习求职经历

『春招实习』2023年3月春招实习求职经历 简介货拉拉一面杭州吉里一面传墨科技一面 简介 3月初我便开始陆续投递简历&#xff0c;直观的感受就是【投递的太晚了】&#xff0c;很多公司很早就开始招聘实习生了。 但是自己一直在担心没准备好&#xff0c;所以就想着再准备一天就投…

数据结构单链表”质检员“*2

1.随机链表的逻辑结构复制 原题链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode-cn.com/problems/copy-list-with…

机器学习:深入解析SVM的核心概念(问题与解答篇)【三、核函数】

核函数 **问题一&#xff1a;为什么说是有限维就一定存在高维空间可分呢&#xff1f;**原始空间与特征空间为什么映射到高维空间可以实现可分核函数的作用 **问题二&#xff1a;最终怎么得到函数**从对偶问题到决策函数的步骤&#xff1a;结论 **问题三&#xff1a;为什么说特征…

Kafka 3.x.x 入门到精通(03)——Kafka基础生产消息

Kafka 3.x.x 入门到精通&#xff08;03&#xff09;——对标尚硅谷Kafka教程 2. Kafka基础2.1 集群部署2.2 集群启动2.3 创建主题2.4 生产消息2.4.1 生产消息的基本步骤2.4.2 生产消息的基本代码2.4.3 发送消息2.4.3.1 拦截器2.4.3.1.1 增加拦截器类2.4.3.1.2 配置拦截器 2.4.3…

c#数据库:1.c#创建并连接数据库

安装软件:SQL Server Management Studio Management Studio Visual Studio 2022 启动服务: 打开SQL Server Management Studio Management Studio ,连接到服务器(GUANZU是我的计算机名) 新建数据库,随便起个名字叫aq: c#代码: using System; using System.Collections.Gener…

UG NX二次开发(C++)-获取模型中所有的拉伸(Extrude)特征

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、在UG 12中创建几个拉伸特征3、UFun中获取对象类型4、通过NXOpen过渡5.测试结果1、前言 在采用UG NX二次开发时,有时需要在模型中获取特定的对象,比如拉伸特征、关联特征等等。但是通过…

大数据分析与应用实验(黑龙江大学)

实验一 Hadoop伪分布式实验环境搭建与WordCount程序 一、实验目的 1、学习搭建Hadoop伪分布式实验环境 2、在伪分布式实验环境下运行WordCount程序 二、实验内容 1、搭建Hadoop伪分布式实验环境&#xff0c;并安装Eclipse。 2、在Eclipse环境下&#xff0c;编写并执行Wor…

面试题:分布式消息中间件 MQ

MQ官网文档&#xff1a; RabbitMQ&#xff1a;https://www.rabbitmq.com/docs RocketMQ&#xff1a;https://rocketmq.apache.org/zh/docs/ Kafka&#xff1a;https://kafka.apache.org/documentation/ DDMQ&#xff1a;https://base.xiaojukeji.com/docs/ddmq 面试题&#xff…

【LeetCode周赛】第 395 场周赛

目录 3131. 找出与数组相加的整数 I 简单3132. 找出与数组相加的整数 II 中等3133. 数组最后一个元素的最小值 中等3134. 找出唯一性数组的中位数 困难 3131. 找出与数组相加的整数 I 简单 3131. 找出与数组相加的整数 I 分析&#xff1a; 将两个数组中最小的两个值相减即可。…

你的动漫AI女友 Anime gf :自定义创建各种独特个性、语言风格的虚拟角色

一个本地且开源的 CharacterAI 替代工具 Anime gf&#xff0c;提供了一个用户友好的界面&#xff0c;允许用户在桌面上与虚拟角色互动。你可以自定义创建各种角色&#xff0c;让每个虚拟角色都有自己的独特个性和语言风格&#xff0c;可以接入OpenAI、Anthropic、Mistral和 Tog…

Faststone Capture:一触即发的效率革命【AI写作】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

XY_RE复现(二)

一&#xff0c;何须相思煮余年 0x55 0x8b 0xec 0x81 0xec 0xa8 0x0 0x0 0x0 0xa1 0x0 0x40 0x41 0x0 0x33 0xc5 0x89 0x45 0xfc 0x68 0x9c 0x0 0x0 0x0 0x6a 0x0 0x8d 0x85 0x60 0xff 0xff 0xff 0x50 0xe8 0x7a 0xc 0x0 0x0 0x83 0xc4…

【中级软件设计师】上午题12-软件工程(3):项目活动图、软件风险、软件评审、软件项目估算

【中级软件设计师】上午题12-软件工程&#xff08;3&#xff09; 1 软件项目估算1.1 COCOMO估算模型1.2 COCOMOⅡ模型 2 进度管理2.1 gantt甘特图2.2 pert图2.3 项目活动图2.3.1 画项目图 3 软件配置管理4 软件风险4.1 风险管理4.2 风险识别4.3 风险预测4.4 风险评估4.5 风险控…

大模型(LLM)调用API论文研究合集

1、API-BLEND: A Comprehensive Corpora for Training and Benchmarking API LLMs 中文标题&#xff1a;API-BLEND: 一个用于训练和评测 API 语言模型的全面语料库 简介&#xff1a;随着大型语言模型(LLM)的发展,它们需要能够有效地利用各种工具和应用程序接口(API)来完成复杂…

GNU Radio之OFDM Channel Estimation底层C++实现

文章目录 前言一、 OFDM Channel Estimation 模块简介二、C 具体实现1、初始化和配置参数2、forecast 函数3、计算载波偏移量4、提取信道响应5、核心的数据处理任务 前言 OFDM Channel Estimation 模块的功能是根据前导码&#xff08;同步字&#xff09;估计 OFDM 的信道和粗略…

Java:SpringBoot如何优化启动速度

一、yml中设置懒加载 spring:main:lazy-initialization: true 二、SpringBoot启动类中添加注解 Indexed &#xff08;Spring5才有该注解&#xff09; Indexed EnableAsync RestController SpringBootApplication(exclude {WxMaAutoConfiguration.class}) EnableTransactionM…

web服务的部署及高级优化

搭建web服务器 1.1、配置主机IP以及软件仓库搭建 [rootserver129 ~]# vmset.sh 100 //主机IP配置为172.25.254.100 1.2、查看搭建web服务器所需的软件包 [rootserver100 ~]# dnf search nginx 名称 精准匹配&#xff1a;nginx nginx.x86_64 : A high performance web serve…

31.基础乐理-首调与固定调

首调与固定调的概念&#xff1a; 首调 与 固定调 这两个词都是针对 唱名 来说的&#xff0c;针对唱名1234567 来说的&#xff0c;和别的没什么关系&#xff0c;这两个概念是唱名的两种不同表达方式 首调&#xff1a;虽然各个大调实际使用的按键、使用的音名都是不一样的&#x…