解释器模式(Interpreter)

解释器模式(Interpreter)

1.意图

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.
如果一种特定类型的问题发生的频率足够高 , 那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器 , 该解释器通过解释这些句子来解决该问题。

2.特点

Expression:抽象表达式,声明一个所有的具体表达式都需要实现的抽象接口;这个接口主要是一个interpret()方法,称做解释操作。
Terminal Expression:终结符表达式,实现了抽象表达式所要求的接口;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
Nonterminal Expression:非终结符表达式,文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+”就是非终结符,解析“+”的解释器就是一个非终结符表达式。
Context:环境,它的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,给R1赋值100,给R2赋值200,这些信息需要存放到环境中。
Client: 构建(或被给定 ) 表示该文法定义的语言中一个特定的句子的抽象语法树。该抽象语法树由Nonterminal Expression和Terminal Expression 的实例装配而成。调用解释操作。

3.UML类图

解释器模式

4.代码

/**
 * 抽象表达式,声明一个所有的具体表达式都需要实现的抽象接口;这个接口主要是一个interpret()方法,称做解释操作
 */
public interface Expression {
    //解释操作
    Integer interpret();

}
/**
 * 终结符表达式,实现了抽象表达式所要求的接口;文法中的每一个终结符都有一个具体终结表达式与之相对应。
 * 比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
 */
public class TerminalExpression implements Expression {
    private Integer i;

    public TerminalExpression(Integer i) {
        this.i = i;
    }

    @Override
    public Integer interpret() {
        return i;
    }
}
/**
 * 非终结符表达式,文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,
 * 比如公式R=R1+R2中,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。
 */
public abstract class NonterminalExpression implements Expression {
    public Expression right;
    public Expression left;

    public NonterminalExpression(Expression right, Expression left) {
        this.right = right;
        this.left = left;
    }

}
public class AddExpression extends NonterminalExpression {


    public AddExpression(Expression right, Expression left) {
        super(right, left);
    }

    @Override
    public Integer interpret() {
        return left.interpret()+right.interpret();
    }
}
public class SubExpression  extends NonterminalExpression {

    public SubExpression(Expression right, Expression left) {
        super(right, left);
    }

    @Override
    public Integer interpret() {
        return right.interpret()-left.interpret();
    }
}
/**
 * 环境,它的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,给R1赋值100,给R2赋值200,这些信息需要存放到环境中。
 */
public class Context {
    private Map<String,TerminalExpression> valueMap = new HashMap<String,TerminalExpression>();

    public void addValue(String key,Integer val){
        valueMap.put(key,new TerminalExpression(val));
    }
    public Integer getValue(String key){
        return valueMap.get(key).interpret();
    }
}
/**
 * 构建(或被给定 ) 表示该文法定义的语言中一个特定的句子的抽象语法树。该抽象语法树由Nonterminal Expression和Terminal Expression 的实例装配而成。调用解释操作。
 */
public class Client {
    //a+b-c
    private String expression;
    private Context context;

    public Client(String expression, Context context) {
        this.expression = expression;
        this.context = context;
    }

    /**
     * 构建表达式语句 计算结果
     * @return
     */
    public int calculate(){
        char[] chars = expression.toCharArray();
        char key = chars[0];
        Integer value = context.getValue(String.valueOf(key));
        TerminalExpression inner = new TerminalExpression(value);
        for (int i=0;i<chars.length;i++){
            if(chars[i]=='+'){
                inner = new TerminalExpression(new AddExpression(inner,new TerminalExpression(context.getValue(String.valueOf(chars[++i])))).interpret());
            }else if(chars[i]=='-'){
                inner = new TerminalExpression(new SubExpression(inner,new TerminalExpression(context.getValue(String.valueOf(chars[++i])))).interpret());
            }
        }
        return inner.interpret();
    }
}
public class InterpreterTest {
    public static void main(String[] args) {
        //构建终端表达式集合
        Context context = new Context();
        context.addValue("a",new Integer(10));
        context.addValue("b",new Integer(2));
        context.addValue("c",new Integer(3));
        Client client = new Client("a+b-c",context);

        System.out.println(client.calculate());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值