解释器模式

目录

1.核心思想

简单来说:

2.成员

3.优点

4.代码实现

4.1 抽象表达式

4.2 终结符表达式

4.3 非终结符表达式

4.4 上下文

4.5 客户端


1.核心思想

定义一个语言的文法,并且建立一个解释器来解释该语言中的语句

简单来说:

有固定的语法结构,类似于加减乘除,数据库的增删改查的一系列固定了语法结构的语句。通过非终结表达式进行运算,终结符表达式来表示值,上下文做扩展,客户端使用。

2.成员

抽象表达式(Abstract Expression)

定义解释器模式中所有表达式的抽象接口或抽象类。通常包含一个 interpret() 方法,用于解释给定的上下文(Context)。

终结符表达式(Terminal Expression)

实现抽象表达式接口,表示文法中的终结符(Terminal Symbols)。终结符表达式是不可再分的基本元素,通常对应文法中的基本单元。

非终结符表达式(Non-terminal Expression)

实现抽象表达式接口,表示文法中的非终结符(Non-terminal Symbols)。非终结符表达式通常由终结符表达式和其他非终结符表达式组成。

上下文(Context)

上下文对象包含解释器解释时需要的全局信息或状态。它维护解释器解释时所需的信息,可能包括文法中的变量、符号表或其他运行时信息。

客户端(Client)

创建或配置解释器并且传递给它解析语言的表达式。客户端通常是使用解释器模式的应用程序或模块。

3.优点

灵活性:解释器模式使得可以轻易地改变和扩展文法,因为它使用类来表示文法规则,每个文法规则可以通过继承或组合来扩展和变化,使得系统更加灵活。

易于实现文法

解释器模式将每个文法规则表示为一个类或表达式,这样更容易理解和实现复杂的文法。

易于扩展:可以通过增加新的表达式来扩展语言的语法,同时可以通过继承或组合已有的表达式来实现新的表达式,这样扩展解释器模式比较容易。

适用于复杂文法:当语法规则非常复杂并且经常变化时,解释器模式比编写复杂的解析器更加简单和灵活。

解耦语法分析和执行:解释器模式通过将语法分析和执行分离,使得可以更容易地管理和修改文法规则,不影响其它部分的代码。

较好的可维护性:解释器模式中的每个表达式可以独立编写、测试和维护,因此系统的可维护性较好

4.代码实现

4.1 抽象表达式

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

4.2 终结符表达式

//终结符表达式
public class NumberExpression extends AbstractExpression{
    private String variableName;

    public NumberExpression(String variableName) {
        this.variableName = variableName;
    }

    @Override
    public int interpreter(Context context) {
        return context.getValue(variableName);
    }
}

4.3 非终结符表达式

// 非终结符表达式:表示加法操作
public class AddExpression extends AbstractExpression{
    private AbstractExpression leftOperand;
    private AbstractExpression rightOperand;

    public AddExpression(AbstractExpression left, AbstractExpression right) {
        this.leftOperand = left;
        this.rightOperand = right;
    }


    @Override
    public int interpreter(Context context) {
        return leftOperand.interpreter(context)+ rightOperand.interpreter(context) ;
    }
}

// 非终结符表达式:表示减法操作
public class SubtractExpression extends AbstractExpression{
    private AbstractExpression leftOperand;
    private AbstractExpression rightOperand;

    public SubtractExpression(AbstractExpression left, AbstractExpression right) {
        this.leftOperand = left;
        this.rightOperand = right;
    }


    @Override
    public int interpreter(Context context) {
        return leftOperand.interpreter(context) - rightOperand.interpreter(context) ;
    }
}

// 非终结符表达式:表示乘法操作
public class MultiplyExpression extends AbstractExpression{
    private AbstractExpression leftOperand;
    private AbstractExpression rightOperand;

    public MultiplyExpression(AbstractExpression left, AbstractExpression right) {
        this.leftOperand = left;
        this.rightOperand = right;
    }


    @Override
    public int interpreter(Context context) {
        return leftOperand.interpreter(context) * rightOperand.interpreter(context) ;
    }
}

// 非终结符表达式:表示除法操作
public class DivideExpression extends AbstractExpression{
    private AbstractExpression leftOperand;
    private AbstractExpression rightOperand;

    public DivideExpression(AbstractExpression left, AbstractExpression right) {
        this.leftOperand = left;
        this.rightOperand = right;
    }


    @Override
    public int interpreter(Context context) {
        int right = rightOperand.interpreter( context);
        if (right != 0) {
            return leftOperand.interpreter(context) / right;
        } else {
            throw new ArithmeticException("被除数不能为0!");
        }
    }
}

4.4 上下文

//上下文类
public class Context {
    private Map<String,Integer> variables =new HashMap();

    public void  setValue(String key,Integer value){
        variables.put(key,value);
    }

    public Integer getValue(String key){


        return variables.get(key); }
}

4.5 客户端

public class Test {
    public static void main(String[] args) {
        //(1 + 2 * 3) / (5 -4)
        Context context = new Context();
        context.setValue("one",1);
        context.setValue("two",2);
        context.setValue("three",3);
        context.setValue("four",4);
        context.setValue("five",5);

        DivideExpression divideExpression = new DivideExpression(
                new AddExpression(
                        new NumberExpression("one")
                        ,

                        new MultiplyExpression(
                                new NumberExpression("two")
                                ,
                                new NumberExpression("three")

                        )
                )
                ,
                new SubtractExpression(
                        new NumberExpression("five")
                        ,
                        new NumberExpression("four")
                )
        );
        int interpreter = divideExpression.interpreter(context);
        System.out.println(interpreter);
    }
}

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值