1. 程式人生 > 實用技巧 >大話設計模式讀書筆記(直譯器模式)

大話設計模式讀書筆記(直譯器模式)

人物:大鳥,小菜

事件:小菜給大鳥說領導找他談話,說他工作不錯,說另一個同事梅星工作一般,大鳥說小菜沒有領會到領導的言外之意,其實領導是側面告訴小菜,你乾的不錯,後面可能需要你多加加油,工作量可能提一提,而同事梅星工作一般,可能領導對他不是很滿意。小菜覺得職場太複雜要是有個翻譯器就好了,大鳥順之引出瞭解釋器模式。


直譯器模式:

1.介紹瞭解釋器模式的概念

2.結構圖

3.直譯器模式程式碼

4.好處與不足

5.小結

直譯器模式

1.概念:給定一個語言(巫師世界的語言),定義它的文法的一種表示(麻瓜),並定義一個直譯器(羅納德·比利爾斯·韋斯萊),這個直譯器使用該表示來解釋言語中的句子(不懂魔法的人類)

2.結構圖:

注:

(1)終結符:終結符直接就代表一個意思,是不可拆分的最小元素,比如關鍵字if就不能再分成i和f了。

(2)非終結符:非終結符可以再分成更細的東西,且不是終結符的都是非終結符。

3.程式碼示意:

前情提要:

(1)什麼是語法樹:是原始碼的抽象語法結構的樹狀表現形式

(2)舉例:foo = 'hello world';

AbstractExpression類,宣告一個抽象的解釋操作,這個介面為抽象語法樹共享:

public abstract class AbstractExpression {
    public abstract void interpret(Context context);
}

TerminalExpression類,實現抽象表示式中所有介面,主要是一個interpret方法,文中每一個終結符都有一個具體終結表示式與之對應:

@Slf4j
public class TerminalExpression extends AbstractExpression {
    @Override
    public void interpret(Context context) {
        log.info("終端直譯器");
    }
}

NonterminalExpressionl類,非終結符表示式,為文中非終結符實現解釋操作:

@Slf4j
public
class NonterminalExpression extends AbstractExpression { @Override public void interpret(Context context) { log.info("非終端直譯器"); } }

Context類,包含直譯器之外的一些全域性資訊:

@Data
public class Context {
    private String input;
    private String output;
}

客戶端程式碼,構建表示該文法定義的語言中一個特定的句子的抽象語法樹,呼叫解釋操作:

public class ExpressionClient {
    public static void main(String[] args) {
        Context context = new Context();
        List<AbstractExpression> list = new ArrayList<>();
        list.add(new TerminalExpression());
        list.add(new NonterminalExpression());
        list.add(new TerminalExpression());
        list.add(new TerminalExpression());

        for (AbstractExpression exp : list) {
            exp.interpret(context);
        }
    }
}

4.好處:用直譯器模式,意味著很容易地改變和擴充套件文法(即語法),因為該模式使用類來標識文法規則,你可以使用繼承來改變或擴充套件該文法,也比較容易實現文法,因為定義抽象語法樹中各節點的類的實現大體類似,這些類都易於直接編寫。

不足:直譯器模式為文法中的每一條規則至少定義了一個類,因此包含許多規則的文法可能難以管理和維護。所以建議當文法複雜時,使用其他程式如語法分析程式或編譯器生成器來處理。

5.小結:直譯器模式就是把一串可能看不懂的字串,通過一系列規則,轉化成看得懂的資訊,或者是把我們常用的資訊,通過規則轉化,轉成機器或者程式碼看得懂的指令。