給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器適用該表示來解釋語言中的句子。java
當有一個語言須要解釋執行,而且你可將該語言中的句子表示爲一個抽象語法樹時,可以使用解釋器模式。而當存在如下狀況時該模式效果最好:express
例:設計模式
S ::= abA*ef A ::= cd
符號「::=」表示推導;符號「*」表示閉包,意思就是符號A能夠有0或有N個重複;S和A稱爲非終結符號,由於他們能推導出式子右邊的表達式,同時又由於整個推導式是從S出發的,所以,這個S也稱爲初始符號;而abef和cd這些字符不能再被推導咱們稱之爲終結符號。數組
靈活的擴展性,當咱們想對文法規則進行擴展延伸時,只須要增長相應的非終結符解釋器,並在構建抽象語法樹時,使用到新增的解釋器對象進行具體的解釋便可,比較方便。閉包
每一條文法都對應一個解釋器,會生成大量類,致使後期維護困難。同時,對於過於複雜的文法,構建其抽象語法樹會顯得異常繁瑣,所以,對於複雜的文法並不推薦使用解釋器模式。ide
表達式「m+n+p」,若是咱們使用解釋器模式對該表達式進行解釋,那麼表明數字的m,n,和p三個字母咱們就能夠當作是終結符號,而「+」這個算術運算符號則可看成非終結符,同時咱們能夠先建立一個抽象解釋器表示數學運算。this
/** * 算術運算解釋器抽象類 * @author newtrekWang * @email wangjiaxing20160101@gmail.com * @time 2018/8/19 23:22 */ public abstract class AthmeticExpression { /** * 抽象的解析方法 * @return 解析獲得的值 */ abstract int interpreter(); } /** * 數字解釋器,只爲了解釋數字 * @author newtrekWang * @email wangjiaxing20160101@gmail.com * @time 2018/8/19 23:24 */ public class NumExpression extends AthmeticExpression { private int num; public NumExpression(int num){ this.num = num; } @Override int interpreter() { return num; } } /** * 運算符解釋器 * @author newtrekWang * @email wangjiaxing20160101@gmail.com * @time 2018/8/19 23:27 */ public abstract class OperatorExpression extends AthmeticExpression { /** * 運算符兩邊的表達式 */ protected AthmeticExpression exp1,exp2; public OperatorExpression(AthmeticExpression exp1, AthmeticExpression exp2) { this.exp1 = exp1; this.exp2 = exp2; } } /** * 加法解釋器 * @author newtrekWang * @email wangjiaxing20160101@gmail.com * @time 2018/8/19 23:29 */ public class AdditionExpressoin extends OperatorExpression { public AdditionExpressoin(AthmeticExpression exp1, AthmeticExpression exp2) { super(exp1, exp2); } /** * 具體解釋+符號 * @return 解釋結果 */ @Override int interpreter() { return exp1.interpreter()+exp2.interpreter(); } } /** * 計算器類 * @author newtrekWang * @email wangjiaxing20160101@gmail.com * @time 2018/8/19 23:30 */ public class Calculator { /** * 用一個棧存儲並操做全部相關的解釋器 */ private Stack<AthmeticExpression> mExpStack = new Stack<>(); public Calculator(String expression){ AthmeticExpression 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 AdditionExpressoin(exp1,exp2)); break; default: // 若是爲數字 mExpStack.push(new NumExpression(Integer.valueOf(elements[i]))); break; } } } /** * 最終結算結果 * @return */ public int calculate(){ return mExpStack.pop().interpreter(); } } public static void main(String[] args){ Calculator calculator = new Calculator("3 + 8 + 2"); System.out.println(calculator.calculate()); }
輸出結果:spa
13