设计模式之解释器模式(上)

解释器模式
1)概述
1.定义

定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。

2.结构图

在这里插入图片描述

3.角色

AbstractExpression(抽象表达式):在抽象表达式中声明了抽象的解释操作,它是所有终结符表达式和非终结符表达式的公共父类。

TerminalExpression(终结符表达式):它实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例,通常在一个解释器模式中只有少数几个终结符表达式类,它们的实例可以通过非终结符表达式组成较为复杂的句子。

NonterminalExpression(非终结符表达式):它实现了文法中非终结符的解释操作,由于在非终结符表达式中可以包含终结符表达式,也可以继续包含非终结符表达式,因此其解释操作一般通过递归的方式来完成。

Context(环境类):环境类又称为上下文类,它用于存储解释器之外的一些全局信息,通常它临时存储了需要解释的语句。

注意

在解释器模式中,每一种终结符和非终结符都有一个具体类与之对应,正因为使用类来表示每一条文法规则,所以系统将具有较好的灵活性和可扩展性。

4.代码实现

抽象表达式类

abstract class AbstractExpression {
       public  abstract void interpret(Context ctx);
}

终结符表达式

public class TerminalExpression extends  AbstractExpression {
       public  void interpret(Context ctx) {
              //终结符表达式的解释操作
       }
}

非终结符表达式

public class NonterminalExpression extends  AbstractExpression {
       private  AbstractExpression left;
       private  AbstractExpression right;

       public  NonterminalExpression(AbstractExpression left,AbstractExpression right) {
              this.left=left;
              this.right=right;
       }

       public void interpret(Context ctx) {
              //递归调用每一个组成部分的interpret()方法
              //在递归调用时指定组成部分的连接方式,即非终结符的功能
       }     
}

环境类

public class Context {
     private HashMap map = new HashMap();

     public void assign(String key, String value) {
          //往环境类中设值
     }

     public String lookup(String key) {
         //获取存储在环境类中的值
     }
}
2)完整解决方案
1.解释过程-抽象语法树

在这里插入图片描述

2.结构图

在这里插入图片描述

AbstractNode充当抽象表达式角色,DirectionNode、ActionNode和DistanceNode充当终结符表达式角色,AndNode和SentenceNode充当非终结符表达式角色。

3.代码实现

抽象表达式

//抽象表达式
abstract class AbstractNode {
    public abstract String interpret();
}

非终结符表达式

//And解释:非终结符表达式
public class AndNode extends AbstractNode {
    private AbstractNode left; //And的左表达式
    private AbstractNode right; //And的右表达式

    public AndNode(AbstractNode left, AbstractNode right) {
        this.left = left;
        this.right = right;
    }

    //And表达式解释操作
    public String interpret() {
        return left.interpret() + "再" + right.interpret();
    }
}

//简单句子解释:非终结符表达式
public class SentenceNode extends AbstractNode {
    private AbstractNode direction;
    private AbstractNode action;
    private AbstractNode distance;

    public SentenceNode(AbstractNode direction, AbstractNode action, AbstractNode distance) {
        this.direction = direction;
        this.action = action;
        this.distance = distance;
    }

    //简单句子的解释操作
    public String interpret() {
        return direction.interpret() + action.interpret() + distance.interpret();
    }
}

终结符表达式

//方向解释:终结符表达式
public class DirectionNode extends AbstractNode {
    private String direction;

    public DirectionNode(String direction) {
        this.direction = direction;
    }

    //方向表达式的解释操作
    public String interpret() {
        if (direction.equalsIgnoreCase("up")) {
            return "向上";
        } else if (direction.equalsIgnoreCase("down")) {
            return "向下";
        } else if (direction.equalsIgnoreCase("left")) {
            return "向左";
        } else if (direction.equalsIgnoreCase("right")) {
            return "向右";
        } else {
            return "无效指令";
        }
    }
}

//动作解释:终结符表达式
public class ActionNode extends AbstractNode {
    private String action;

    public ActionNode(String action) {
        this.action = action;
    }

    //动作(移动方式)表达式的解释操作
    public String interpret() {
        if (action.equalsIgnoreCase("move")) {
            return "移动";
        } else if (action.equalsIgnoreCase("run")) {
            return "快速移动";
        } else {
            return "无效指令";
        }
    }
}

//距离解释:终结符表达式
public class DistanceNode extends AbstractNode {
    private String distance;

    public DistanceNode(String distance) {
        this.distance = distance;
    }

    //距离表达式的解释操作
    public String interpret() {
        return this.distance;
    }
}

工具类InstructionHandler用于对输入指令进行处理,将输入指令分割为字符串数组,将第1个、第2个和第3个单词组合成一个句子,并存入栈中;如果发现有单词“and”,则将“and”后的第1个、第2个和第3个单词组合成一个新的句子作为“and”的右表达式,并从栈中取出原先所存句子作为左表达式,然后组合成一个And节点存入栈中,依此类推,直到整个指令解析结束。

import java.util.Stack;

//指令处理类:工具类
public class InstructionHandler {
    private AbstractNode node;

    public void handle(String instruction) {
        AbstractNode left = null, right = null;
        AbstractNode direction = null, action = null, distance = null;

        //声明一个栈对象用于存储抽象语法树
        Stack stack = new Stack();
        //以空格分隔指令字符串
        String[] words = instruction.split(" ");

        for (int i = 0; i < words.length; i++) {
            if (words[i].equalsIgnoreCase("and")) {
                //弹出栈顶表达式作为左表达式
                left = (AbstractNode) stack.pop();
                String word1 = words[++i];
                direction = new DirectionNode(word1);
                String word2 = words[++i];
                action = new ActionNode(word2);
                String word3 = words[++i];
                distance = new DistanceNode(word3);
                right = new SentenceNode(direction, action, distance); //右表达式
                stack.push(new AndNode(left, right)); //将新表达式压入栈中
            } else {
                //如果是从头开始进行解释,则将前三个单词组成一个简单句子SentenceNode并将该句子压入栈中
                String word1 = words[i];
                direction = new DirectionNode(word1);
                String word2 = words[++i];
                action = new ActionNode(word2);
                String word3 = words[++i];
                distance = new DistanceNode(word3);
                left = new SentenceNode(direction, action, distance);
                //将新表达式压入栈中
                stack.push(left);
            }
        }
        this.node = (AbstractNode) stack.pop(); //将全部表达式从栈中弹出
    }

    public String output() {
        return node.interpret();
    }
}

客户端类

public class Client {
    public static void main(String[] args) {
        String instruction = "up move 5 and down run 10 and left move 5";
        InstructionHandler handler = new InstructionHandler();
        handler.handle(instruction);

        String outString;
        outString = handler.output();
        System.out.println(outString);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PQMII-T20-C-A的控制功能

PQMII-T20-C-A 是一款电力质量监测仪器&#xff0c;它能够提供三相系统的连续监控。 以下是关于PQMII-T20-C-A的一些详细信息&#xff1a; 多参数测量&#xff1a;该设备具备测量电流、电压、有功功率、无功功率、能源使用、电力成本、功率因数和频率等关键电力参数的能力。波…

阿里云2024年优惠券获取方法及使用教程详解

阿里云是阿里巴巴集团旗下的云计算服务提供商&#xff0c;是全球领先的云计算及人工智能科技公司之一。提供免费试用、云服务器、云数据库、云安全、云企业应用等云计算服务&#xff0c;以及大数据、人工智能服务、精准定制基于场景的行业解决方案。 阿里云2024年优惠券的获取方…

jeecg-boot 3.6使用微服务启动详细配置

1&#xff1a;运行sql文件 2&#xff1a;配置host 路径如下 127.0.0.1 jeecg-boot-redis 127.0.0.1 jeecg-boot-mysql 127.0.0.1 jeecg-boot-nacos 127.0.0.1 jeecg-boot-gateway 127.0.0.1 jeecg-boot-system 127.0.0.1 jeecg-boot-xxljob 127.0.0.1 jeecg-boot-rabbitmq 3…

基于springboot现服装销售平台系统项目【项目源码+论文说明】

基于springboot实现服装销售平台系统演示 摘要 随着信息互联网购物的飞速发展&#xff0c;一般企业都去创建属于自己的电商平台以及购物管理系统。本文介绍了“衣依”服装销售平台的开发全过程。通过分析企业对于“衣依”服装销售平台的需求&#xff0c;创建了一个计算机管理“…

系统架构评估_3.ATAM方法

架构权衡分析方法&#xff08;Architecture Tradeoff Analysis Method&#xff0c;ATAM&#xff09;是在SAAM的基础发展起来的&#xff0c;主要针对性能、实用性、安全性和可修改性&#xff0c;在系统开发之前&#xff0c;对这些质量属性进行评价和折中。 &#xff08;1&#x…

uniapp请求后端接口

新建文件夹utils const request (config) > {// 拼接完整的接口路径config.url http://mm.test.cn config.url;//这里拼接的是访问后端接口的地址&#xff0c;http://mm.test.cn/prod-api/testconsole.log(config.url)//判断是都携带参数if(!config.data){config.data …

【御控物联】 JavaScript JSON结构转换(20):数组To对象——转换映射方式

文章目录 一、JSON结构转换是什么&#xff1f;二、术语解释三、案例之《JSON数组 To JSON对象》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0…

AI识别技术详解 --在windows环境中部署基于YOLO v8模型的目标检测

首先 YOLO是一个端到端的目标检测算法&#xff0c;一次前向传播计算&#xff0c;实现图像的多目标检测任务&#xff0c;我么可以在ultralytics官网上查看YOLO的各个版本&#xff08;v1-v8&#xff09;以及源码 使用YOLO v8提供的python接口&#xff0c;训练一个佩戴安全帽的目标…

简介:基于Web的产品3D

基于 Web 的产品 3D 通过可视化界面获得各种选项来个性化他们的产品&#xff0c;例如颜色、材料、尺寸、文字、徽标、零件等。 在过去几年中&#xff0c;随着 3D 建模和渲染软件的出现&#xff0c;3D 渲染现在更常用于营销和促销目的。设计师、制造商和营销人员使用 3D 产品渲…

Windows 11安装Radialix 3

Radialix 3软件可以实现软件汉化&#xff0c;能够制作汉化补丁和语言包文件。 接下来详细介绍安装过程&#xff0c;亲测有效。 一、下载安装包并本地解压 安装包资源和破解软件都上传到了文章顶部。 本地解压&#xff1a; 二、开始安装Radialix 双击Radialix_3.00.00.486.…

RuleEngine规则引擎底层改造AviatorScript 之公式规则

前情提要&#xff0c;看上一个文章&#xff0c;具体要实现的效果就是 当然上来的问题就是前端的问题&#xff0c;这个框首先他们用的是富文本&#xff0c;富文本传到后台的结果是前端脚本&#xff0c;带着h5的标签&#xff0c;后面改成了这个&#xff0c;当时这个东西其实和后…

springboot系列-自定义启动时狂拽酷炫的banner信息

springboot系列-自定义启动时狂拽酷炫的banner信息 基于springboot 2.6.6 jdk1.8 代码地址&#xff1a;github仓库地址 banner module 更多系列教程请关注公众号’coderlike’ 如果觉得有帮助希望能关注下公众号 本篇短文只说明文本类型的banner打印 添加配置到applica…

谷歌建站用什么程序比较好?

建网站这回事&#xff0c;说容易也容易&#xff0c;现如今市面上建站的程序多如牛毛&#xff0c;哪怕你不会代码也能建一个漂亮的网站&#xff0c;但网站搭建出来是为了什么&#xff1f;是为了获取流量&#xff0c;拉到业务&#xff0c;那么&#xff0c;建站的时候你就要考虑谷…

可视化大屏的应用(9):智慧旅游和智慧景区

可视化大屏在智慧旅游领域具有多种价值&#xff0c;可以为旅游管理者和游客提供更加便捷、优质的服务和体验。本期大千UI工场带来智慧旅游和智慧景区的可视化大屏界面&#xff0c;供大家欣赏。 可视化大屏在智慧旅游领域的价值如下&#xff1a; 提供全面的信息展示&#xff0…

基于springboot实现明星周边产品销售网站项目【项目源码+论文说明】计算机毕业设计

基于springboot实现明星周边产品销售网站系统演示 摘要 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#xff0c;针对这个问题开发一个专门适应洗衣店业务新的交流形式的网站。本文介绍了星之语明星周边产品销售网站的开发全过程。通过分析企业对于星之…

上岸第一剑,编程语法必修:python并发编程

前言 回顾昨天的内容&#xff0c;昨天从基础入门&#xff0c;列表与元组&#xff0c;字符串&#xff0c;字典&#xff0c;条件循环和其他语句&#xff0c;函数&#xff0c;面向对象编程&#xff0c;异常与文件处理等八个方向讲述了python语法编程&#xff0c;今天来到第二章py…

【CSDN活动】人工智能:前沿科技中的创业机遇与挑战

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 人工智能&#xff1a;前沿科技中的创业机遇与挑战一、AI技术的快速发展与应用拓…

C++手撕红黑树

文章目录 红黑树概念性质&#xff08;条件限制&#xff09;节点的定义红黑树的结构红黑树的插入cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;u存在且为红cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;u不存在或u为黑&#xff0c;插入到p对应的一边cur为红…

Vue3报错:‘defineProps‘ is not defined no-undef

解决方法 在package.json中添加 "vue/setup-compiler-macros": true 记得在上面的 "node": true 后面加一个逗号 "eslintConfig": {"root": true,"env": {"node": true,"vue/setup-compiler-macros": t…

考PMP一定要培训吗?PMP备考可不是说着玩的

想要考项目管理认证一定要培训吗&#xff1f;其实这是必要的也是必须的啦&#xff0c;不仅仅是因为自学的难度大&#xff0c;个人自学很难总结学习技巧&#xff0c;另一个原因就是考试前还必须要有授权培训机构提供的35学时培训证明&#xff0c;没有这个培训证明也就直接意味着…