21、设计模式之解释器模式【难】

定义

给定一个语言,定义的它文法(描述语言的语法结构)表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。‘’

文法规则:

  1. expression ::= value | plus | minus
  2. plus ::= expression ‘+’ expression
  3. minus ::= expression ‘-’ expression
  4. value ::= integer

注意:这里的“::=”表示“定义为”的意思,竖线 | 表示或,引号内为字符本身,引号外为语法。
上述的规则可以描述为:表达式可以是一个值,也可以是plus或minus运算,而plus和minus又是由表达式结合运算符构成,值的类型为整型数。

结构

  • 抽象表达式(Abstract Expression):定义解释器的接口,约定解释器的解释操作,主要包含解释方法。
  • 终结符表达式(Terminal Expression):是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
  • 非终结符表达式(Nonterminal Expression):是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中每条规则都对应于一个非终结符表达式。
  • 环境(Context):通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
  • 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

案例

实现加减法的软件:比如1+2-3+4、1+3+4+3-6-5等。

在这里插入图片描述
环境类

package com.hupp.interpreter;

import java.util.HashMap;
import java.util.Map;

public class Context {
    
    
    //定义一个map集合,用来存储变量及对应的值
    private Map<Variable,Integer> map = new HashMap<>();

    //添加变量
    public void assign(Variable var,Integer value){
    
    
        map.put(var,value);
    }

    public int getValue(Variable var){
    
    
        return map.get(var);
    }

}

变量类

package com.hupp.interpreter;

/**
 * 封装变量的类
 */
public class Variable extends AbstractExpression{
    
    
    //用于存储变量名
    private String name;

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

    @Override
    public int interpret(Context context) {
    
    
        return context.getValue(this);
    }

    @Override
    public String toString() {
    
    
        return name;
    }
}

抽象表达式类

package com.hupp.interpreter;

/**
 * 抽象表达式
 */
public abstract class AbstractExpression {
    
    
    public abstract int interpret(Context context);
}

加法表达式和减法表达式类

package com.hupp.interpreter;

/**
 * 加法表达式
 */
public class Plus extends AbstractExpression {
    
    

    //加号左边的表达式
    private AbstractExpression left;
    //加号右边的表达式
    private AbstractExpression right;

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

    @Override
    public int interpret(Context context) {
    
    
        //将左边表达式的结果和右边表达式的结果进行相加
        return left.interpret(context)+right.interpret(context);
    }

    @Override
    public String toString() {
    
    
        return "("+left.toString()+"+"+right.toString()+")";
    }
}

package com.hupp.interpreter;

/**
 * 减法表达式
 */
public class Minus extends AbstractExpression {
    
    
    //加号左边的表达式
    private AbstractExpression left;
    //加号右边的表达式
    private AbstractExpression right;

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

    @Override
    public int interpret(Context context) {
    
    
        //将左边表达式的结果和右边表达式的结果进行相减
        return left.interpret(context)-right.interpret(context);
    }

    @Override
    public String toString() {
    
    
        return "("+left.toString()+"-"+right.toString()+")";
    }
}

客户端类

package com.hupp.interpreter;

public class Client {
    
    
    public static void main(String[] args) {
    
    
        //创建环境对象
        Context context = new Context();

        //创建多个变量
        Variable a = new Variable("a");
        Variable b = new Variable("b");
        Variable c = new Variable("c");
        Variable d = new Variable("d");

        context.assign(a, 1);
        context.assign(b, 2);
        context.assign(c, 3);
        context.assign(d, 4);

        //获取抽象语法树 a + b - c + d
        AbstractExpression expression = new Minus(a, new Plus(new Minus(b, c), d));

        //解释
        int result = expression.interpret(context);

        System.out.println(expression + "=" + result);


    }
}

在这里插入图片描述

Guess you like

Origin blog.csdn.net/hpp3501/article/details/112006972