美文网首页Android开发Android进阶Android开发
化繁为简的翻译机——解释器模式

化繁为简的翻译机——解释器模式

作者: 程序员丶星霖 | 来源:发表于2019-01-28 10:23 被阅读9次

    《Android源码设计模式解析与实战》读书笔记(十)
    《Android源码设计模式解析与实战》PDF资料下载

    一、解释器模式的简介

    解释器模式是一种行为型模式,其提供了一种解释语言的语法或表达式的方式,该模式定义了一个表达式接口,通过该接口解释一个特定的上下文。

    1.1、定义

    给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

    1.2、使用场景

    1. 如果某个简单的语言需要解释执行而且可以将该语言中的语句表示为一个抽象语法树时可以考虑使用解释器模式;
    2. 在某些特定的领域出现不断重复的问题时,可以将该领域的问题转化为一种语法规则下的语句,然后构建解释器来解释该语句。

    二、解释器模式的简单实现

    public abstract class ArithmeticExpression {
        /**
         * 抽象的解析方法
         * 具体的解析逻辑由具体的子类实现
         */
        public abstract int interpret();
    }
    
    public class NumExpression extends ArithmeticExpression {
        private int num;
    
        public NumExpression(int num) {
            this.num = num;
        }
    
        @Override
        public int interpret() {
            return num;
        }
    }
    
    public abstract class OperatorExpression extends ArithmeticExpression {
        //声明两个成员变量存储格式两边的数字解释器
        protected ArithmeticExpression exp1,exp2;
    
        public OperatorExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {
            this.exp1 = exp1;
            this.exp2 = exp2;
        }
    }
    
    public class AdditionExpressiom extends OperatorExpression {
        public AdditionExpressiom(ArithmeticExpression exp1, ArithmeticExpression exp2) {
            super(exp1, exp2);
        }
    
        @Override
        public int interpret() {
            return exp1.interpret() + exp2.interpret();
        }
    }
    
    public class Calcultator {
        //声明一个Stack栈存储并操作所有相关的解释器
        private Stack<ArithmeticExpression> mExpStack = new Stack<>();
    
        public Calcultator(String expression) {
            //声明两个ArithmeticExpression类型的临时变量,存储运算符左右两边的数字解释器
            ArithmeticExpression exp1, exp2;
    
            //根据空格分割表达式字符串
            String[] elements = expression.split(" ");
    
            /**
             * 循环遍历表达式元素数组
             */
            for (int i = 0; i < elements.length; i++) {
                /**
                 * 判断运算符号
                 */
                switch (elements[i].charAt(0)) {
                    case '+'://如果是加号
                        //则将栈中的解释器弹出作为运算符号左边的解释器
                        exp1 = mExpStack.pop();
                        //同时将运算符号数组下标下一个元素构造为一个数字解释器
                        exp2 = new NumExpression(Integer.valueOf(elements[++i]));
                        //通过上面两个数字解释器构造加法运算解释器
                        mExpStack.push(new AdditionExpressiom(exp1, exp2));
                        break;
                    default://如果为数字
                        /**如果不是运算符则为数字
                         * 若是数字,直接构造数字解释器并压入栈
                         */
                        mExpStack.push(new NumExpression(Integer.valueOf(elements[i])));
                        break;
                }
            }
        }
    
        /**
         * 计算结果
         */
        public int calculate() {
            return mExpStack.pop().interpret();
        }
    }
    
    Calcultator c = new Calcultator("153 + 3589 + 118 + 555");
            System.out.println(c.calculate());
    

    输出结果:

    4415
    

    三、总结

    3.1、优点

    解释器模式最大的优点是其灵活的扩展性,当想对文法规则进行扩展延伸时,只需要增加相应的非终结符解释器,并在构建抽象语法树时,使用到新增的解释器对象进行具体的解释即可,非常方便。

    3.2、缺点

    因为对每一条文法都可以对应至少一个解释器,其会生成大量的类,导致后期维护苦难。同时,过于复杂的文法,构建其抽象语法树会显得异常繁琐,甚至有可能会出现需要构建多棵抽象语法树的情况。因此,对于复杂的文法并不推荐使用解释器模式。

    学海无涯苦作舟

    我的微信公众号

    相关文章

      网友评论

        本文标题:化繁为简的翻译机——解释器模式

        本文链接:https://www.haomeiwen.com/subject/xxjjjqtx.html