java设计模式(行为型)之解释器模式

第0章:简介

解释器模式的定义:定义语言的文法,并且建立一个解释器来解释该语言中的句子。客户端可以使用这个解释器来解释这个语言中的句子。

解释器模式的本质:解释语言的语法或表达式的方式

参考:研磨设计模式(书籍),大话设计模式(书籍),图解设计模式(书籍)

模式图:

待补充

第1章:实践

(1)抽象表达式类(AbstractExpression.java)

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 抽象表达式类
 * (也可以用接口类)
 *
 * 本例文法:
 * expression ::= plus | minus | variable | number
 * plus       ::= expression expression '+'
 * minus      ::= expression expression '-'
 * variable   ::= 'a' | 'b' | 'c' | ... | 'z'
 * digit      ::= '0' | '1' | ... | '9'
 * number     ::= digit | digit number
 *
 * 表达式例子:
 * a b +
 * a b c + -
 * a b + c a - -
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public abstract class AbstractExpression {

    /**
     * 解释方法
     * @param context 上下文环境对象
     */
    public abstract int interpret(Context context);
}
(2)数字(number)终结符表达式类NumberTerminalExpression.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 数字(number)终结符表达式类
 *
 * 文法中的每一个终结符都有一个具体终结表达式与之相对应
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public class NumberTerminalExpression extends AbstractExpression {

    private int number;

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

    /**
     * 实现文法中与终结符number有关的解释操作
     * @param context 上下文环境对象
     */
    @Override
    public int interpret(Context context) {
        return number;
    }
}

(3)变量(Variable)终结符表达式类VariableTerminalExpression.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 变量(Variable)终结符表达式类
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public class VariableTerminalExpression extends AbstractExpression {

    //变量名称
    private String name;

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

    public String getName(){
        return name;
    }

    /**
     * 实现文法中与终结符变量有关的解释操作
     * @param context 上下文环境对象
     * @return
     */
    @Override
    public int interpret(Context context) {

        return context.getValue(this);
    }
}

(4)加操作(Plus)非终结符表达式PlusNonterminalExpression.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 加操作(Plus)非终结符表达式
 *
 * 文法中的每一条规则都需要一个具体的非终结符表达式,
 * 非终结符表达式一般是文法中的运算符或者其他关键字。
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public class PlusNonterminalExpression extends AbstractExpression {

    //加操作左边表达式
    private AbstractExpression leftExpression;
    //加操作右边表达式
    private AbstractExpression rightExpression;

    public PlusNonterminalExpression(AbstractExpression leftExpression, AbstractExpression rightExpression){
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    /**
     *实现文法中与非终结符加有关的解释操作
     * @param context 上下文环境对象
     * @return
     */
    @Override
    public int interpret(Context context) {
        return leftExpression.interpret(context) + rightExpression.interpret(context);
    }
}

(5)减操作(Minus)非终结符表达式MinusNonterminalExpression.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 减操作(Minus)非终结符表达式
 *
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/30.
 */
public class MinusNonterminalExpression extends AbstractExpression {

    //减操作左边表达式
    private AbstractExpression leftExpression;
    //减操作右边表达式
    private AbstractExpression rightExpression;

    public MinusNonterminalExpression(AbstractExpression leftExpression, AbstractExpression rightExpression){
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    /**
     * 实现文法中与非终结符减有关的解释操作
     * @param context 上下文环境对象
     * @return
     */
    @Override
    public int interpret(Context context) {
        return leftExpression.interpret(context) - rightExpression.interpret(context);
    }
}
(6)上下文环境类(Context.java

package com.mcc.core.designPattern.behavior.interpreter;

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

/**
 * 上下文环境类
 * 为解释器进行语法解释提供了必要信息
 *
 * 解释器的定义:定义语言的文法,并且建立一个解释器来解释该语言中的句子。客户端可以使用这个解释器来解释这个语言中的句子。
 * 解释器的本质:解释语言的语法或表达式的方式
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/29.
 */
public class Context {

    //用于存放变量实例和对应值
    private Map<VariableTerminalExpression, Integer> valueMap = new HashMap<VariableTerminalExpression, Integer>();
    //用于存放变量名和对应实例
    private Map<String, VariableTerminalExpression> vriableTerminalExpressionMap = new HashMap<String, VariableTerminalExpression>();

    /**
     * 增加变量实例和对应值
     * @param variable
     * @param value
     */
    public void addValue(VariableTerminalExpression variable, Integer value){
        valueMap.put(variable,value);
        vriableTerminalExpressionMap.put(variable.getName(), variable);
    }

    /**
     * 获取变量实例的值
     * @param variable
     * @return
     */
    public int getValue(VariableTerminalExpression variable){
        if(valueMap != null){
            return (Integer)valueMap.get(variable).intValue();
        }else{
            System.out.println("此处处理异常");
            return 0;
        }

    }

    /**
     * 解释语法树
     * @param expression
     * @return
     */
    public int parse(String expression){
        Stack<AbstractExpression> expressionStack = new Stack<AbstractExpression>();
        for (String token : expression.split(" ")) {
            //加操作处理
            if  (token.equals("+")) {
                AbstractExpression subExpression = new PlusNonterminalExpression(expressionStack.pop(), expressionStack.pop());
                expressionStack.push( subExpression );
            }
            //减操作处理
            else if (token.equals("-")) {
                // it's necessary remove first the right operand from the stack
                AbstractExpression rightExpression = expressionStack.pop();
                // ..and after the left one
                AbstractExpression leftExpression = expressionStack.pop();
                AbstractExpression subExpression = new MinusNonterminalExpression(leftExpression, rightExpression);
                expressionStack.push( subExpression );
            }
            else
                expressionStack.push( vriableTerminalExpressionMap.get(token) );
        }
        AbstractExpression abstractExpression = expressionStack.pop();

        return abstractExpression.interpret(this);
    }
}

(7)客户端测试(Client.java

package com.mcc.core.designPattern.behavior.interpreter;

/**
 * 客户端测试
 *
 * @author <a href="mailto:[email protected]">menergy</a>
 *         My blog: https://blog.csdn.net/menergy
 *         Created by Administrator on 2018/4/30.
 */
public class Client {
    public static void main(String args[]){
        String expression = "w x z - +";
        Context context = new Context();
        context.addValue(new VariableTerminalExpression("w"),5);
        context.addValue(new VariableTerminalExpression("x"),10);
        context.addValue(new VariableTerminalExpression("z"),42);
        //解释器解释并返回结果
        int result = context.parse(expression);

        System.out.println(result);
    }
}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章