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

news2024/11/24 19:32:55
解释器模式
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);
    }
}

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

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

相关文章

聚观早报 | 高德地图Vision Pro版上线;谷歌照片升级编辑功能

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 4月12日消息 高德地图Vision Pro版上线 谷歌照片升级编辑功能 首款苹果DockKit配件推出 华为推出新品FreeLace P…

第6章 6.3.1 正则表达式的语法(MATLAB入门课程)

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 正则表达式可以由一般的字符、转义字符、元字符、限定符等元素组…

git push报错remote: Please remove the file from history and try again

原因&#xff1a;上传文件超过100M&#xff0c;找到此文件删除即可。 1、查看是哪个文件过大&#xff0c;此处对用红框里面的 a6de1336c67c3bac77757c5eff8c8001823f7c92&#xff0c;得到具体的文件名称 git rev-list --objects --all | grep a6de1336c67c3bac77757c5eff8c80…

亿发:互联网时代,生产企业信息化管理平台的建设应用指南

越来越多的企业家和高管朋友开始意识到&#xff0c;在互联网时代&#xff0c;生产企业信息化建设的重要性&#xff0c;但在实际推动过程中常常缺乏方向&#xff0c;不知从何处入手。 根据当前的调查数据显示&#xff0c;尽管信息化建设已经基本成型&#xff0c;各种信息化系统…

AI升降梯人数监测识别摄像机

AI升降梯人数监测识别摄像机是一种基于人工智能技术的智能监控设备&#xff0c;被广泛应用于楼宇、商场、办公楼等场所的升降梯监测和管理。这种摄像机能够通过摄像头捕捉乘客进出升降梯的信息&#xff0c;利用AI算法对人数进行实时监测和识别&#xff0c;从而提供智能管理和安…

IP地址的主要功能及其在网络中的重要性

在当今数字化时代&#xff0c;互联网已经成为人们生活和工作中不可或缺的一部分。而IP地址&#xff08;Internet Protocol Address&#xff09;作为互联网中的关键组成部分&#xff0c;发挥着至关重要的作用。本文将探讨IP地址的主要功能以及其在网络中的重要性。 IP地址查询&…

力扣题目 19:删除链表的倒数第N个节点 【python】

&#x1f464;作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a; 码上找工作http://t.csdnimg.cn/Q59WX 作者专栏每日更新&#xff1a; LeetCod…

适配器模式类图与代码

某软件系统中&#xff0c;已设计并实现了用于显示地址信息的类Address,现要求提供基于Dutch语言的地址信息显示接口。为了实现该要求并考虑到以后可能还会出现新的语言的接口&#xff0c;决定采用适配器(Adapter)模式实现该要求&#xff0c;得到如图7.9所示的类图。 【Java代码…

软件测试学习之MySQL学习笔记(完结)

目录 1. 数据库**** 1.1. 概念**** 1.2. 分类**** 1.2.1. 关系型数据库**** 1.2.1.1. SQL**** 1.2.2. 安装**** 1.2.2.1. Navicat**** 2. SQL语句**** 2.1. 常用数据类型**** 2.2. 数据库**** 2.3. 表**** 2.3.1. 字段约束**** 2.4. 数据**** 2.4.1. 增 insert**…

Java 中文官方教程 2022 版(三)

原文&#xff1a;docs.oracle.com/javase/tutorial/reallybigindex.html 对象 原文&#xff1a;docs.oracle.com/javase/tutorial/java/javaOO/objects.html 一个典型的 Java 程序会创建许多对象&#xff0c;正如您所知&#xff0c;这些对象通过调用方法进行交互。通过这些对象…

Prompt 工程技术提问的艺术,如何向 ChatGPT 提问?

Prompt 工程技术简介 什么是 Prompt 工程&#xff1f; Prompt 工程是创建提示或指导像 ChatGPT 这样的语言模型输出的过程。它允许用户控制模型的输出并 生成符合其特定需求的文本。ChatGPT 是一种先进的语言模型&#xff0c;能够生成类似于人类的文本。它建立在 Transformer 架…

【Linux学习】初识Linux指令(一)

文章目录 1.指令操作与图形化界面操作1.什么是指令操作&#xff0c;什么是图形化界面操作&#xff1f; 2.Linux下基本指令1.Linux下的复制粘贴2.Linux两个who命令3.补充知识4.pwd指令5. ls 指令6.cd 指令1.目录树2.相对路径与绝对路劲3.常用cd指令 7.tree指令8. touch指令9.sta…

[python] Numpy库用法(持续更新)

先导入一下 import numpy as np 一、np.random用法 生成随机整数&#xff1a;np.random.randint(low, high, size) low: 最小值high: 最大值size: 生成的数组大小&#xff08;可以是多维&#xff0c;下面同理&#xff09; 生成随机浮点数&#xff1a;np.random.uniform(low, …

LongVLM:让大模型解读长视频 SOTA 的方法

LongVLM&#xff1a;让大模型解读长视频 SOTA 的方法 使用LongVLM处理长视频的步骤LongVLM 方法3.1 总体架构3.2 局部特征聚合3.3 全局语义整合 效果4.1 实验设置4.2 主要结果4.3 消融研究4.4 定性结果 论文&#xff1a;https://arxiv.org/pdf/2404.03384.pdf 代码&#xff1a…

java混淆的重要性分析

Java代码混淆是一种常用的安全技术&#xff0c;它通过对Java代码进行变换和重命名&#xff0c;使得源代码变得难以理解和逆向工程&#xff0c;从而增强代码的安全性。以下是对Java混淆重要性的分析&#xff1a; 保护知识产权&#xff1a;Java混淆可以防止恶意用户或竞争对手轻易…

算法:树形dp(树状dp)

文章目录 一、树形DP的概念1.基本概念2.解题步骤3.树形DP数据结构 二、典型例题1.LeetCode&#xff1a;337. 打家劫舍 III1.1、定义状态转移方程1.2、参考代码 2.ACWing&#xff1a;285. 没有上司的舞会1.1、定义状态转移方程1.2、拓扑排序参考代码1.3、dfs后序遍历参考代码 一…

【可视化大屏开发】18. 加餐-ECharts+百度地图API实现热力图

ECharts结合百度地图API能获得更好的使用体验。 效果展示 放大后的效果 切换卫星地图模式 实现步骤 1. 通过Python实现GPS数据模拟 2. 通过IDEA开发地图 通过Python实现GPS数据模拟 import random from math import cos, sin, radians, sqrt import jsondef generate_random…

【web网页制作】html+css网页制作学校网站主题校园网页(5页面)【附源码】

学校网页制作目录 涉及知识写在前面一、网页主题二、网页效果Page1、简介Page2、校园风光Page3、学术研究Page4、校训阐述Page5、留言 三、网页架构与技术3.1 脑海构思3.2 整体布局3.3 技术说明书 四、网页源码4.1 主页模块源码4.2 源码获取方式 作者寄语 涉及知识 学校网站主…

【云计算】云网络产品体系概述

云网络产品体系概述 在介绍云网络产品体系前&#xff0c;先介绍几个与云计算相关的基础概念。 阿里云在基础设施层面分为 地域 和 可用区 两层&#xff0c;关系如下图所示。在一个地域内有多个可用区&#xff0c;每个地域完全独立&#xff0c;每个可用区完全隔离&#xff0c;同…

低噪声、低电压、低功耗特点的双运算放大器D722

概述 Silicore D722具有低噪声、低电压、低功耗特点的双运算放大器&#xff0c;具有9MHz的高增益带宽积&#xff0c;转换率为8.5V/μs, 5V时静态电流为0.97mA&#xff0f;每个放大器。适用于低电压和低噪声场合的应用系统&#xff0c;它提供轨到轨的输出摆幅&#xff0c;符合工…