23种设计模式--解释器模式---Interpreter

参考:https://blog.youkuaiyun.com/weixin_48052161/article/details/119716593
这是我们23个设计模式中最后一个设计模式了,大家或许也没想到吧,竟然是编译原理上的编译器,这样说可能不对,因为编译器分为几个部分组成呢,比如词法分析器、语法分析器、语义分析器、中间代码优化器以及最终的最终代码生成器。而这个解释器其实就是完成了对语法的解析,将一个个的词组解释成了一个个语法范畴,之后拿来使用而已。

为什么会有这个解释器模式呢,我想这是从编译原理中受到启发的,使用了这样的一个解释器可以在Java语言之上在定义一层语言,这种语言通过Java编写的解释器可以放到Java环境中去执行,这样如果用户的需求发生变化,比如打算做其他事情的时候,只用在自己定义的新的语言上进行修改,对于Java编写的代码不需要进行任何的修改就能在Java环境中运行,这是非常有用的。这就好像,虽然不管怎么编译,最终由中间代码生成最终代码(机器码)是依赖于相应的机器的。但是编译器却能理解高级语言和低级语言,无论高级语言的程序是怎么样编写的,编译器的代码是不用修改的,而解释器模式就是想做一个建立在Java和我们自定义语言之间的编译器。

给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
解释器模式(Interpreter Pattern)是指给定一门语言,定义它的文法的一种表示(如:加减乘除表达式和正则表达式等),然后再定义一个解释器,该解释器用来解释我们的文法表示(表达式)。
解释器模式是一种按照规定的语法(文法)来进行解析的一种设计模式,属于行为型模式

解释器模式:相当于自己设计一种语言处理算法;
代码演示:
案例 1 :计算器
需求:
模拟简单的加减法表达式

在这里插入图片描述
抽象表达式角色接口类: IExpression

package com.example.dtest.design23.interpreter;

public interface IExpression {
    int interpret();
}

继承接口类的抽象的非终结表达式: AbstractNonTerminalExpression

package com.example.dtest.design23.interpreter;
/**
 * 非终结表达式-抽象表达式
 */
public abstract class AbstractNonTerminalExpression implements IExpression{

    //protected类型,因为子类要继承
    protected IExpression leftExpression;
    protected IExpression rightExpression;

    public AbstractNonTerminalExpression(IExpression leftExpression,IExpression rightExpression){
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }


}

继承接口的终结表达式角色类: NumberExpression

package com.example.dtest.design23.interpreter;

public class NumberExpression implements IExpression{

    private int value;

    public NumberExpression(String value){
        this.value = Integer.valueOf(value);
    }

    @Override
    public int interpret() {
        return this.value;
    }
}

具体非终结表达式角色类,继承抽象类: AddExpression , SubExpression
本次示例中只列举加法和减法,所以我们还需要一个加法类和一个减法类:
AddExpression 加法类

package com.example.dtest.design23.interpreter;

public class AddExpression extends AbstractNonTerminalExpression{

    public AddExpression(IExpression leftExpression,IExpression rightExpression){
        super(leftExpression,rightExpression);
    }

    @Override
    public int interpret() {
        return this.leftExpression.interpret() + this.rightExpression.interpret();
    }
}

SubExpression 减法类

package com.example.dtest.design23.interpreter;

public class SubExpression extends AbstractNonTerminalExpression{

    public SubExpression(IExpression leftExpression,IExpression rightExpression){
        super(leftExpression,rightExpression);
    }

    @Override
    public int interpret() {
        return this.leftExpression.interpret() - this.rightExpression.interpret();
    }
}

上下文环境角色门面类:ExpressionContext

package com.example.dtest.design23.interpreter;

import java.util.Stack;

public class ExpressionContext {

    private Integer currValue;//记录当前运算结果,空表示暂未运算
    private Stack<IExpression> stack = new Stack<>();

    public ExpressionContext(String expression){
        this.parse(expression);
    }

    private void parse(String expression){
        String[] elementArr = expression.split(" ");
        for(int i=0;i<elementArr.length;i++){
            String element = elementArr[i];
            if(element.equals("+")){
                IExpression leftExpression = stack.pop();//栈类元素出栈
                IExpression rightExpression = new NumberExpression(elementArr[++i]);//取出+号后的下一个元素
                IExpression addExpression = new AddExpression(leftExpression, rightExpression);
                stack.push(new NumberExpression(addExpression.interpret()+ ""));//将计算结果入栈
            }else if(element.equals("-")){
                IExpression leftExpression = stack.pop();//栈内元素出栈
                IExpression rightExpression = new NumberExpression(elementArr[++i]);//取出-号后的下一个元素
                IExpression subExpression = new SubExpression(leftExpression, rightExpression);
                stack.push(new NumberExpression(subExpression.interpret() + ""));//将计算结果入栈
            }else {
                stack.push(new NumberExpression(element));//如果是数字则直接入栈
            }
        }
    }

    public int calcuate(){
        return stack.pop().interpret();//经过前面解析,到这里stack内只会剩下唯一一个数字,即运算结果
    }


}

测试类:

package com.example.dtest.design23.interpreter;

public class TestInterpreter {

    public static void main(String[] args) {

        ExpressionContext context = new ExpressionContext("1 + 1 - 1");
        System.out.println(context.calcuate());
        context = new ExpressionContext("10 - 20 + 10");
        System.out.println(context.calcuate());

    }

}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值