解釋器模式(interpreter)java
定義:給定一種語言,定義他的方法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中的句子。
git
類型:形爲型模式 github
順口溜:中訪策備迭 觀模命狀職解sql
package com.amosli.dp.interpreter; public class Context { private String input; private String output; public String getInput() { return input; } public void setInput(String input) { this.input = input; } public String getOutput() { return output; } public void setOutput(String output) { this.output = output; } } package com.amosli.dp.interpreter; public abstract class AbstractExpression { public abstract void interpreter(Context context); } package com.amosli.dp.interpreter; public class NonTerminalExpression extends AbstractExpression { @Override public void interpreter(Context context) { System.out.println("this is NonTerminalExpression !"); } } package com.amosli.dp.interpreter; public class TerminalExpression extends AbstractExpression { @Override public void interpreter(Context context) { System.out.println("this is terminal expression!!!"); } } package com.amosli.dp.interpreter; import java.util.ArrayList; import java.util.List; public class Client { public static void main(String[] args) { Context context = new Context(); List<AbstractExpression> expressions = new ArrayList<AbstractExpression>(); expressions.add(new TerminalExpression()); expressions.add(new NonTerminalExpression()); expressions.add(new TerminalExpression()); for (AbstractExpression abstractExpression : expressions) { abstractExpression.interpreter(context); } } }
抽象解釋器:聲明一個全部具體表達式都要實現的抽象接口(或者抽象類),接口中主要是一個interpret()方法,稱爲解釋操做。具體解釋任務由它的各個實現類來完成,具體的解釋器分別由終結符解釋器TerminalExpression和非終結符解釋器NonterminalExpression完成。express
終結符表達式:實現與文法中的元素相關聯的解釋操做,一般一個解釋器模式中只有一個終結符表達式,但有多個實例,對應不一樣的終結符。終結符一半是文法中的運算單元,好比有一個簡單的公式R=R1+R2,在裏面R1和R2就是終結符,對應的解析R1和R2的解釋器就是終結符表達式。 ide
非終結符表達式:文法中的每條規則對應於一個非終結符表達式,非終結符表達式通常是文法中的運算符或者其餘關鍵字,好比公式R=R1+R2中,+就是非終結符,解析+的解釋器就是一個非終結符表達式。非終結符表達式根據邏輯的複雜程度而增長,原則上每一個文法規則都對應一個非終結符表達式。工具
環境角色:這個角色的任務通常是用來存放文法中各個終結符所對應的具體值,好比R=R1+R2,咱們給R1賦值100,給R2賦值200。這些信息須要存放到環境角色中,不少狀況下咱們使用Map來充當環境角色就足夠了。this
解釋器是一個簡單的語法分析工具,它最顯著的優勢就是擴展性,修改語法規則只須要修改相應的非終結符就能夠了,若擴展語法,只須要增長非終結符類就能夠了。spa
1)維護成本高code
解釋器模式會引發類的膨脹,每一個語法都須要產生一個非終結符表達式,語法規則比較複雜時,就可能產生大量的類文件,爲維護帶來很是多的麻煩。
2)過於複雜時效率低
同時,因爲採用遞歸調用方法,每一個非終結符表達式只關心與本身相關的表達式,每一個表達式須要知道最終的結果,必須經過遞歸方式,不管是面向對象的語言仍是面向過程的語言,遞歸都是一個不推薦的方式。因爲使用了大量的循環和遞歸,效率是一個不容忽視的問題。特別是用於解釋一個解析複雜、冗長的語法時,效率是難以忍受的。
本系列文章源碼地址,https://github.com/amosli/dp 歡迎Fork & Star !!