行为型:解释器模式

news2025/6/2 9:32:13

目录

1、核心思想

2、实现方式

2.1 模式结构

2.2 实现案例

3、优缺点分析

4、适用场景

5、注意事项


1、核心思想

目的:针对某种语言并基于其语法特征创建一系列的表达式类(包括终极表达式与非终极表达式)​,利用树结构模式将表达式对象组装起来,最终将其翻译成计算机能够识别并执行的语义树。

概念:解释器模式其实就是一种组合模式的特殊应用,它巧妙地利用了组合模式的数据结构,基于上下文生成表达式(解释器)组合起来的语义树,最终通过逐级递进解释完成上下文的解析。

核心思想:将每个语法规则表示为一个类,通过组合这些类实现复杂语法的解析

举例

1> 结构型数据库对查询语言SQL的解析

2> 浏览器对HTML语言的解析

3> 操作系统Shell对命令的解析

4> 数学公式

5> 正则表达式

2、实现方式

2.1 模式结构

五个核心角色:

  • AbstractExpression(抽象表达式)​:定义解释器的标准接口interpret(),所有终极表达式类与非终极表达式类均需实现此接口。
  • TerminalExpression(终极表达式)​:抽象表达式接口的实现类,具有原子性、不可拆分性的表达式。表示语法中的基本元素(如变量、常量),直接完成具体的解释操作。
  • NonTerminalExpression(非终极表达式)​:抽象表达式接口的实现类,包含一个或多个表达式接口引用,所以它所包含的子表达式可以是非终极表达式,也可以是终极表达式。表示语法中的组合规则(如运算、逻辑表达式),通过递归调用子表达式完成解释。
  • Context(上下文)​:需要被解释的语言类,它包含符合解释器语法规则的具体语言。存储解释器需要的全局信息(如变量值、环境配置)。
  • Client(客户端)​:构建语法树并触发解释操作。

2.2 实现案例

实现一个简单的加减法解释器,支持变量替换(如 x + y - 2):

//1、抽象表达式
public interface Expression {
    int interpret(Context context);
}

//2、终极表达式
// 变量表达式(终结符)
public class Variable implements Expression {
    private String name;

    public Variable(String name) {
        this.name = name;
    }

    @Override
    public int interpret(Context context) {
        return context.getValue(name); // 从上下文中获取变量值
    }
}

// 数字表达式(终结符)
public class Number implements Expression {
    private int value;

    public Number(int value) {
        this.value = value;
    }

    @Override
    public int interpret(Context context) {
        return value; // 直接返回数字值
    }
}

//3、非终极表达式
// 加法表达式(非终结符)
public class Add implements Expression {
    private Expression left;
    private Expression right;

    public Add(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {
        return left.interpret(context) + right.interpret(context);
    }
}

// 减法表达式(非终结符)
public class Subtract implements Expression {
    private Expression left;
    private Expression right;

    public Subtract(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {
        return left.interpret(context) - right.interpret(context);
    }
}

//4、上下文:存储变量值
import java.util.HashMap;
import java.util.Map;

public class Context {
    private Map<String, Integer> variables = new HashMap<>();

    public void setValue(String name, int value) {
        variables.put(name, value);
    }

    public int getValue(String name) {
        return variables.getOrDefault(name, 0);
    }
}

//5、客户端:构建语法树并解释
public class Client {
    public static void main(String[] args) {
        Context context = new Context();
        context.setValue("x", 5);
        context.setValue("y", 3);

        // 构建表达式:x + y - 2
        Expression expression = new Subtract(
            new Add(new Variable("x"), new Variable("y")),
            new Number(2)
        );

        int result = expression.interpret(context);
        System.out.println("计算结果:" + result); // 输出:6(5+3-2=6)
    }
}

3、优缺点分析

优点:

  • 易于扩展语法:新增语法规则只需添加新的表达式类。

  • 符合单一职责原则:每个表达式类只负责一个语法规则。

  • 灵活组合:通过嵌套表达式实现复杂逻辑。

缺点:

  • 类数量膨胀:复杂语法需要大量表达式类,增加维护难度。

  • 执行效率低:递归解释可能导致性能问题。

  • 难以处理复杂语法:对层级嵌套较多的语法(如编程语言)支持较差。

4、适用场景

  • 领域特定语言(DSL)

    • 如SQL条件解析、金融规则引擎、游戏技能脚本。

  • 简单语法解析

    • 如数学表达式、布尔逻辑表达式、配置文件解析。

  • 需要动态扩展语法

    • 如工作流引擎中的条件分支配置。

5、注意事项

  • 避免过度设计

    • 若语法简单且稳定,可直接使用现成的解析库(如ANTLR、JavaCC)。

  • 优化性能

    • 对高频调用的解释器,可预编译表达式或缓存中间结果。

  • 处理语法错误

    • 需在解释过程中添加语法校验和异常处理逻辑。

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

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

相关文章

linux 1.0.3

挂载 这个虚拟机啥时候都能挂起 会有一个这个东东 选择连接虚拟机&#xff0c;然后就连到linux了 这有两个键&#xff0c;一个是和主机连接一个是和虚拟机连接 先把U盘拔掉 原本是没有这个盘的&#xff0c;但是插上去之后&#xff0c;电脑创建了一个虚拟的盘 也就是图中的F…

C#集合循环删除某些行

你想要在遍历集合&#xff08;例如List&#xff09;的同时删除某些元素时&#xff0c;直接在循环中删除元素可能会导致问题&#xff0c;因为这可能会改变集合的大小和导致索引问题&#xff1b; 可以用for循环的倒序来删除&#xff1b; 如果要删除满足特定条件的所有元素&…

【Linux 学习计划】-- 进程地址空间

目录 进程地址的引入 进程地址空间基础原理 区域划分的本质 如何理解进程地址空间 越界访问的本质 进一步理解写时拷贝 重谈 fork 返回值 结语 进程地址的引入 我们先来看一段代码&#xff1a; 首先我们可以看到&#xff0c;父进程和子进程是可以同时可以看到一个变量…

CTFHub-RCE 命令注入-过滤空格

观察源代码 代码里面可以发现过滤了空格 判断是Windows还是Linux 源代码中有 ping -c 4 说明是Linux 查看有哪些文件 127.0.0.1|ls 打开flag文件 我们尝试将空格转义打开这个文件 利用 ${IFS} 127.0.0.1|cat${IFS}flag_195671031713417.php 可是发现 文本内容显示不出来&…

Express教程【002】:Express监听GET和POST请求

文章目录 2、监听post和get请求2.1 监听GET请求2.2 监听POST请求 2、监听post和get请求 创建02-app.js文件。 2.1 监听GET请求 1️⃣通过app.get()方法&#xff0c;可以监听客户端的GET请求&#xff0c;具体的语法格式如下&#xff1a; // 1、导入express const express req…

【PostgreSQL 03】PostGIS空间数据深度实战:从地图服务到智慧城市

PostGIS空间数据深度实战&#xff1a;从地图服务到智慧城市 关键词 PostGIS, 空间数据库, 地理信息系统, GIS, 空间查询, 地理分析, 位置服务, 智慧城市, 空间索引, 坐标系统 摘要 PostGIS是PostgreSQL的空间数据扩展&#xff0c;它将普通的关系数据库转变为强大的地理信息系统…

HIT-csapp大作业:程序人生-HELLO‘s P2P

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 计算学部 学  号 2023111813 班 级 23L0518 学 生 鲁永哲 指 导 教 师 史先俊 计…

深入探讨redis:主从复制

前言 如果某个服务器程序&#xff0c;只部署在一个物理服务器上就可能会面临一下问题(单点问题) 可用性问题&#xff0c;如果这个机器挂了&#xff0c;那么对应的客户端服务也相继断开性能/支持的并发量有限 所以为了解决这些问题&#xff0c;就要引入分布式系统&#xff0c…

帕金森常见情况解读

一、身体出现的异常节奏​ 帕金森会让身体原本协调的 “舞步” 出现错乱。它是一种影响身体行动能力的状况&#xff0c;随着时间推进&#xff0c;就像老旧的时钟&#xff0c;齿轮转动不再顺畅&#xff0c;使得身体各个部位的配合逐渐失衡&#xff0c;打乱日常行动的节奏。​ …

清华大学发Nature!光学工程+神经网络创新结合

2025深度学习发论文&模型涨点之——光学工程神经网络 清华大学的一项开创性研究成果在《Nature》上发表&#xff0c;为光学神经网络的发展注入了强劲动力。该研究团队巧妙地提出了一种全前向模式&#xff08;Fully Forward Mode&#xff0c;FFM&#xff09;的训练方法&…

【android bluetooth 案例分析 04】【Carplay 详解 3】【Carplay 连接之车机主动连手机】

1. 背景 在前面的文章中&#xff0c;我们已经介绍了 carplay 在车机中的角色划分&#xff0c; 并实际分析了 手机主动连接车机的案例。 感兴趣可以 查看如下文章介绍。 【android bluetooth 案例分析 04】【Carplay 详解 1】【CarPlay 在车机侧的蓝牙通信原理与角色划分详解】…

C++学习-入门到精通【11】输入/输出流的深入剖析

C学习-入门到精通【11】输入/输出流的深入剖析 目录 C学习-入门到精通【11】输入/输出流的深入剖析一、流1.传统流和标准流2.iostream库的头文件3.输入/输出流的类的对象 二、输出流1.char* 变量的输出2.使用成员函数put进行字符输出 三、输入流1.get和getline成员函数2.istrea…

NW969NW978美光闪存颗粒NW980NW984

NW969NW978美光闪存颗粒NW980NW984 技术解析&#xff1a;NW969、NW978、NW980与NW984的架构创新 美光&#xff08;Micron&#xff09;的闪存颗粒系列&#xff0c;尤其是NW969、NW978、NW980和NW984&#xff0c;代表了存储技术的前沿突破。这些产品均采用第九代3D TLC&#xf…

使用 ssld 提取CMS 签名并重签名

拿SpringBoard的cms签名和entitlements.xml&#xff0c;对tihook.dylib进行重签名 工具来源&#xff1a;https://github.com/eksenior/ssld

大厂前端研发岗位PWA面试题及解析

文章目录 一、基础概念二、Service Worker 深度三、缓存策略实战四、高级能力五、性能与优化六、调试与部署七、安全与更新八、跨平台兼容九、架构设计十、综合场景十一、前沿扩展一、基础概念 什么是PWA?列举3个核心特性 解析:渐进式网页应用。核心特性:离线可用、类原生体…

第十四章 MQTT订阅

系列文章目录 系列文章目录 第一章 总体概述 第二章 在实体机上安装ubuntu 第三章 Windows远程连接ubuntu 第四章 使用Docker安装和运行EMQX 第五章 Docker卸载EMQX 第六章 EMQX客户端MQTTX Desktop的安装与使用 第七章 EMQX客户端MQTTX CLI的安装与使用 第八章 Wireshark工具…

腾讯云推出云开发AI Toolkit,国内首个面向智能编程的后端服务

5月28日&#xff0c;腾讯云开发 CloudBase 宣布推出 AI Toolkit&#xff08;CloudBase AI Toolkit&#xff09;&#xff0c;这是国内首个面向智能编程的后端服务&#xff0c;适配 Cursor 等主流 AI 编程工具。 云开发 AI Toolkit旨在解决 AI 辅助编程的“最后一公里”问题&…

前端-不对用户显示

这是steam的商店偏好设置界面&#xff0c;在没有被锁在国区的steam账号会有5个选项&#xff0c;而被锁在国区的账号只有3个选项&#xff0c;这里使用的技术手段仅仅在前端隐藏了这个其他两个按钮。 单击F12打开开发者模式 单击1处&#xff0c;找到这一行代码&#xff0c;可以看…

WPF【10_2】数据库与WPF实战-示例

客户预约关联示例图 MainWindow.xaml 代码 <Window x:Class"WPF_CMS.MainWindow" xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d"ht…

Cursor奇技淫巧篇(经常更新ing)

Dot files protection &#xff1a;Cursor当开启了Agent模式之后可以自动帮我们写文件&#xff0c;但是一般项目中的一些配置文件&#xff08;通常以.开头的&#xff09;都是非常重要性&#xff0c;为了防止Cursor在运行的过程中自己修改这些文件&#xff0c;导致风险&#xff…