化繁爲簡的翻譯機——解釋器模式

《Android源碼設計模式解析與實戰》讀書筆記(十) 《Android源碼設計模式解析與實戰》PDF資料下載php

1、解釋器模式的簡介

解釋器模式是一種行爲型模式,其提供了一種解釋語言的語法或表達式的方式,該模式定義了一個表達式接口,經過該接口解釋一個特定的上下文。express

1.一、定義

給定一個語言,定義它的文法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中的句子。設計模式

1.二、使用場景

  1. 若是某個簡單的語言須要解釋執行並且能夠將該語言中的語句表示爲一個抽象語法樹時能夠考慮使用解釋器模式;
  2. 在某些特定的領域出現不斷重複的問題時,能夠將該領域的問題轉化爲一種語法規則下的語句,而後構建解釋器來解釋該語句。

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、總結

3.一、優勢

解釋器模式最大的優勢是其靈活的擴展性,當想對文法規則進行擴展延伸時,只須要增長相應的非終結符解釋器,並在構建抽象語法樹時,使用到新增的解釋器對象進行具體的解釋便可,很是方便。bash

3.二、缺點

由於對每一條文法均可以對應至少一個解釋器,其會生成大量的類,致使後期維護苦難。同時,過於複雜的文法,構建其抽象語法樹會顯得異常繁瑣,甚至有可能會出現須要構建多棵抽象語法樹的狀況。所以,對於複雜的文法並不推薦使用解釋器模式。微信

學海無涯苦做舟

個人微信公衆號
相關文章
相關標籤/搜索