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

解释器模式

时间:2024-01-25 20:22:45浏览次数:15  
标签:解释器 String secondExpression firstExpression 模式 Interpreter public interpret

  • 定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
  • 简单来说:为了解释一种语言而为语言创建的解释器
  • 类型:行为型
  • 适用场景:某个特定类型问题发生频率足够高
  • 优点:语法由很多类表示,容易改变及扩展此“语言”
  • 缺点:当语法规则数目太多时,增加了系统复杂度
  • 相关设计模式:
    • 解释器模式和适配器模式:有点类似,但是适配器模式不需要预先知道要适配的规则,而解释器要把规则写好,根据规则去执行解释

Coding

  • 场景:实现6 100 11 + *按顺序数字入栈,遇到符号出栈计算结果
/**
 * 解释器接口以及它的三个实现类
 */
public interface Interpreter {
    int interpret();
}
public class AddInterpreter implements Interpreter {
    private Interpreter firstExpression,secondExpression;

    public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
        this.firstExpression = firstExpression;
        this.secondExpression = secondExpression;
    }

    @Override
    public int interpret() {
        return this.firstExpression.interpret() + this.secondExpression.interpret();
    }

    @Override
    public String toString() {
        return "+";
    }
}
public class MultiInterpreter implements Interpreter {

    private Interpreter firstExpression, secondExpression;

    public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
        this.firstExpression = firstExpression;
        this.secondExpression = secondExpression;
    }

    @Override
    public int interpret() {
        return this.firstExpression.interpret() * this.secondExpression.interpret();
    }

    @Override
    public String toString() {
        return "*";
    }
}
public class NumberInterpreter implements Interpreter {

    private int number;

    public NumberInterpreter(int number) {
        this.number = number;
    }

    public NumberInterpreter(String number) {
        this.number = Integer.parseInt(number);
    }

    @Override
    public int interpret() {
        return this.number;
    }
}
public class ExpressionParser {
    private Stack<Interpreter> stack = new Stack<Interpreter>();

    public int parse(String str) {
        String[] strItemArray = str.split(" ");
        for (String symbol : strItemArray) {
            if (!OperatorUtil.isOperator(symbol)) {
                Interpreter numberExpression = new NumberInterpreter(symbol);
                stack.push(numberExpression);
                System.out.println(String.format("入栈: %d", numberExpression.interpret()));
            } else {
                //是运算符号,可以计算
                Interpreter firstExpression = stack.pop();
                Interpreter secondExpression = stack.pop();
                System.out.println(String.format("出栈: %d 和 %d",
                        firstExpression.interpret(), secondExpression.interpret()));
                Interpreter operator = OperatorUtil.getExpressionObject(firstExpression, secondExpression, symbol);
                System.out.println(String.format("应用运算符: %s", operator));
                int result = operator.interpret();
                NumberInterpreter resultExpression = new NumberInterpreter(result);
                stack.push(resultExpression);
                System.out.println(String.format("阶段结果入栈: %d", resultExpression.interpret()));
            }
        }
        int result = stack.pop().interpret();
        return result;
    }
}
public class OperatorUtil {
    public static boolean isOperator(String symbol) {
        return (symbol.equals("+") || symbol.equals("*"));
    }

    public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol) {
        if (symbol.equals("+")) {
            return new AddInterpreter(firstExpression, secondExpression);
        } else if (symbol.equals("*")) {
            return new MultiInterpreter(firstExpression, secondExpression);
        }
        return null;
    }
}

 

测试

public class Test {
    public static void main(String[] args) {
        String inputStr = "6 100 11 + *";
        ExpressionParser expressionParser = new ExpressionParser();
        int result = expressionParser.parse(inputStr);
        System.out.println("解释器计算结果: " + result);
    }
}
============输出================
入栈: 6
入栈: 100
入栈: 11
出栈: 11 和 100
应用运算符: +
阶段结果入栈: 111
出栈: 111 和 6
应用运算符: *
阶段结果入栈: 666
解释器计算结果: 666

 

UML

IMG_256

源码中的应用

java.util.regex.Pattern:正则表达式就是一种语法,通过JDK中的正则解释器把它解释出来

public final class Pattern
    implements java.io.Serializable
{
    private int parsePastWhitespace(int ch) {
        while (ASCII.isSpace(ch) || ch == '#') {
            while (ASCII.isSpace(ch))
                ch = temp[cursor++];
            if (ch == '#')
                ch = parsePastLine();
        }
        return ch;
    }
    /**
     * xmode parse past comment to end of line.
     */
    private int parsePastLine() {
        int ch = temp[cursor++];
        while (ch != 0 && !isLineSeparator(ch))
            ch = temp[cursor++];
        return ch;
    }

 

标签:解释器,String,secondExpression,firstExpression,模式,Interpreter,public,interpret
From: https://www.cnblogs.com/wangzhilei-src/p/17988083

相关文章

  • .NET GC的SustainedLowLatency模式引发内存的问题
    最近遇到一个问题,应用的内存占用升上去后一直降不下来,打了dump文件后发现GC的Generation0上有很多空白区间没释放,按道理第0代堆是经常回收的,怎么会有那么多空白区间呢?查阅了相关文档后,发现这是由代码中的System.Runtime.GCSettings.LatencyMode=System.Runtime.GCLatencyMode......
  • goland开启debug模式的修复
    1、使用下载的老版golandide工具,使用debug模式无法正常生效:异常信息是因为goland中的dlv.exe版本太老,也就是dlv.exe不能适配最新的go版本:errorlayer=debuggercouldnotpatchruntime.mallogc:notypeentryfound,use'types'foralistof2、处理方案:goinstallg......
  • Centos桌面模式和命令行模式切换
    希望在VMware中的CentOS虚拟机默认启动到命令行模式(无桌面模式),而不是图形用户界面(GUI),可以按照以下步骤操作:打开终端,使用以下命令获取当前的默认目标(target),如果是图形模式,通常会显示graphical.target。systemctlget-default将默认目标设置为多用户模式,这是一个无桌面的......
  • 探讨Go语言中的HTTP代理模式:看Go如何玩转网络中转站
    在互联网的海洋中,HTTP代理服务器像一座灯塔,为我们的网络冲浪提供了指引。而当Go语言遇上HTTP代理,会碰撞出怎样的火花呢?今天,让我们一起探讨Go语言中的HTTP代理模式,看看它如何玩转这个网络中转站!首先,让我们来了解一下什么是HTTP代理模式。简而言之,HTTP代理模式就是通过一个代理服务器......
  • db2设置归档模式
    环境:Os:Centos7DB:V11.5.61.查看数据库是否处于归档模式[db2inst1@host135SQL00001]$db2getdbcfgfordb_hxl|grepLOGARCHFirstlogarchivemethod(LOGARCHMETH1)=OFFArchivecompressionforlogarchmeth1(LOGARCHCOMPR1)=OFFOptio......
  • 用C++11打造智能观察者模式:详解实现步骤完整示例代码
     观察者模式是一种行为设计模式,其中一个对象(主题)维护其依赖对象(观察者)的列表,当主题的状态发生变化时,它通知所有观察者。以下是一个使用C++11实现观察者模式的简单例子:定义观察者接口(Observer): 创建一个观察者接口,该接口包含观察者需要实现的更新方法。这个接口可以包含其他......
  • Python设计模式:你的代码真的够优雅吗?
    当涉及到代码优化时,Python作为一种高级编程语言,具有广泛的应用领域和强大的功能。在软件开发中,设计模式是一种被广泛采用的解决问题的方案,它提供了一种在特定情境中重复使用的可行方案。在Python中,有许多设计模式可以用来优化代码。其中两种常见的设计模式是单例模式和工厂模式。......
  • 《设计模式:可复用面向对象软件的基础》PDF
    内容简介本书结合设计实例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中*有价值的经验,并且用简洁可复用的形式表达出来。本书分类描述了一组设计良好、表达清楚的软件设计模式,这些模式在实用环境下特别有用。本书适合大学计算机专业的学生、研究生及相关人......
  • 《设计模式之美》PDF
    内容简介本书结合真实项目案例,从面向对象编程范式、设计原则、代码规范、重构技巧和设计模式5个方面详细介绍如何编写高质量代码。第1章为概述,简单介绍了本书涉及的各个模块,以及各个模块之间的联系;第2章介绍面向对象编程范式;第3章介绍设计原则;第4章介绍代码规范;第5章介绍重构技巧;......
  • jax框架为例:求hession矩阵时前后向模式的自动求导的性能差别
    注意:本文相关基础知识不介绍。给出代码:fromjaximportjacfwd,jacrevimportjax.numpyasjnpdefhessian_1(f):returnjacfwd(jacrev(f))defhessian_2(f):returnjacfwd(jacfwd(f))defhessian_3(f):returnjacrev(jacfwd(f))defhessian_4(f):......