🎯 什麼情境該想到我
當你「有一種簡單、而且文法穩定不太會變的小語言或規則,想把它的句子解讀出來」的時候(例如查詢過濾條件、簡單的算術/布林運算式、輕量的規則 DSL)。
⚙️ 怎麼用(步驟 / 公式)
意圖:給定一種語言,定義它的文法的一種表示,並定義一個直譯器,用該表示來解釋語言中的句子。
主要參與者 / 結構:
- AbstractExpression(抽象運算式):宣告
interpret(context)。 - TerminalExpression(終結符運算式):對應文法中的終結符(如變數、字面值)。
- NonterminalExpression(非終結符運算式):對應文法規則(如 And、Or、Add),內部持有子運算式,遞迴呼叫子節點的
interpret()。 - Context(上下文):存放解讀時需要的全域資訊(如變數值)。
做法要點:
- 把文法的每一條規則對應成一個類別,組成類別階層。
- 一個句子被表示成一棵抽象語法樹(由終結符與非終結符節點組成)。
- 對樹遞迴呼叫
interpret(),逐層求值得到結果。 - 適合文法簡單、規則穩定、且句子會反覆出現的場合。
🧪 我實際套用的紀錄
- (待填)
⚠️ 注意 / 什麼時候不適用
- 文法一複雜,類別數量就爆炸,維護困難——這是本模式最大的痛點。
- 只適合簡單、穩定的語言;真正複雜的語言請改用正規的 parser/語法分析器產生器。
- 效能上,遞迴解讀大量句子可能不理想。
🔗 相關工具
- 組合模式 Composite(語法樹本身就是一種組合結構,終結/非終結符即葉子與組合節點)
- 訪問者模式 Visitor(想在語法樹上加多種操作又不想改節點類別時,常搭配訪問者)
- 迭代器模式 Iterator(走訪語法樹的節點)
- 工具-針對介面編程(各節點只依賴 AbstractExpression 介面)
- 設計模式