设计模式_20_解释器模式

基本介绍

  1. 在编译原理中, -一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成-颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器
  2. 解释器模式(Interpreter Pattern) :是指给定一一个语言 (表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)
  3. 应用场景
    ● 应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树
    ● 一些重复出现的问题可以用一种简单的语言来表达
    ● 一个简单语法需要解释的场景
  4. 这样的例子还有,比如编译器、运算表达式计算、正则表达式、机器人等

例子:
使用解释器模式完成加减运算


image.png
public abstract class Expression {

    public abstract int interpret(HashMap<String, Integer> var);
    
}

public class VarExpression extends Expression{
    
    private String key;

    public VarExpression(String key) {
        super();
        this.key = key;
    }

    @Override
    public int interpret(HashMap<String, Integer> var) {
        // TODO Auto-generated method stub
        return var.get(this.key);
    }

}
public class SymbolExpression extends Expression{

     protected Expression left;
     protected Expression right;
     
     
     
    public SymbolExpression(Expression left, Expression right) {
        super();
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(HashMap<String, Integer> var) {
        // TODO Auto-generated method stub
        return 0;
    }
    
}

public class AddExpression extends SymbolExpression {
    
    

    public AddExpression(Expression left, Expression right) {
        super(left, right);
        // TODO Auto-generated constructor stub
    }

    @Override
    public int interpret(HashMap<String, Integer> var) {
        // TODO Auto-generated method stub
        return super.left.interpret(var)+super.right.interpret(var);
    }

}

public class SubExpression extends SymbolExpression{

    public SubExpression(Expression left, Expression right) {
        super(left, right);
        // TODO Auto-generated constructor stub
    }

    @Override
    public int interpret(HashMap<String, Integer> var) {
        // TODO Auto-generated method stub
         return super.left.interpret(var) - super.right.interpret(var);
    }

}

public class Caculator {
    
    Expression expression;
    Expression left;
    Expression right;
    
    public Caculator(String expStr) {
        // TODO Auto-generated constructor stub
        Stack<Expression> stack = new Stack<>();
        char[] cs = expStr.toCharArray();
        
        for(int i=0; i<cs.length;i++){
            switch (cs[i]) {
            case '+':
                 left = stack.pop();
                 right = new VarExpression(String.valueOf(cs[++i]));
                 stack.push(new AddExpression(left, right));
                break;
            case '-':
                 left = stack.pop();
                 right = new VarExpression(String.valueOf(cs[++i]));
                 stack.push(new SubExpression(left, right));
                 break;
            default:
                expression = new VarExpression(String.valueOf(cs[i]));
                stack.push(expression);
                break;
            }
        }
        this.expression = stack.pop();
    }
    
    public int run(HashMap<String, Integer> var){
        return this.expression.interpret(var);
    }

}

public class Client {
    
    public static void main(String[] args) {
        
        String expStr ="a+b-c+d";
        HashMap<String, Integer> var = new HashMap<>();
        var.put("a", 10);
        var.put("b", 50);
        var.put("c", 80);
        var.put("d", 40);       
        Caculator caculator = new Caculator(expStr);        
        System.out.println(caculator.run(var));
    }
}

解释器模式的注意事项和细节

  1. 当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性
  2. 应用场景:编译器、运算表达式计算、正则表达式、机器人等;
  3. 使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。