領域專用語言實戰
Debasish Ghosh[美]
2013.11出版
元編程:編寫“編寫代碼”的代碼。元編程可以通過編寫程序來產生新的程序,也能改變已有程序的行爲。
常用的DSL
DSL | 用途 |
---|---|
SQL | 關係型數據庫 |
Ant, Rake, Make | 幾種用於軟件系統構建的語言 |
CSS, HTML | web開發預言 |
YACC, Bison, ANTLR | 幾種用例生產語法分析器的語言 |
RSpec、Cucumber | Ruby環境下的行爲驅動測試語言 |
lombok | Java-JSR-269-插入式註解處理器,編譯器修改源代碼 |
AspectJ | 面向切面編程aspect-oriented programming |
java字節碼技術
- 動態代理 java自身使用的動態代理
- CGLIB
- javassist
- asm
java元編程能力
- jdk裏的javap,用來反彙編class文件查看生成的字節碼
- org.objectweb.asm 用來解析、修改、保存字節碼的代碼庫
- fernflower.jar 用來批量將class文件反編譯成java代碼(當然idea也可以手動單個反編譯)
- java的Instrumentation,可以編寫代碼使用javaagent代理執行其它java文件,在代碼裏使用上面的asm庫動態修改代碼。也可以直接將所有字節保存,並加載其它class文件。
設計DSL結構的原則
- DSL要爲問題域製品提供直接的映射
- DSL腳本必須使用問題域的共通語彙
- DSL腳本必須對底層實現進行抽象
DSL的分類
內部DSL
-
內嵌式
實現模式 工具箱 靈巧API 連貫接口、java語言、Ruby語言 反射式元編程 Ruby\Groovy隱式上下文、Ruby語言動態裝飾器 類型化內嵌 Scala語言類型化的抽象 語法樹操作 - 元編程模式:
- 隱式上下文和靈巧API
- 利用動態裝飾器的反射式元編程
- 利用builder的反射式元編程
- 類型化抽象模式
- 運用高階函數使抽象泛化
- 運用顯式類型約束建模領域邏輯
- 元編程模式:
-
生成式
實現模式 工具箱 編譯時元編程 通過宏來進行代碼生成,Clojure語言 運行時元編程 運行時代碼生成、Ruby語言
外部DSL
- 上下文驅動的字符串
- XML轉換成可使用的資源
- DSL工作臺
- DSL中內嵌異質代碼
- 基於解析器組合子的DSL設計
內部DSL的集成入口
內部DSL的集成模式 | 集成入口 |
---|---|
JAVA腳本引擎 | 用Groovy等腳本語言編寫的DSL可以通過java腳本引擎來集成 |
DSL包裝器 | 利用JRuby, Scala,Groovy等語言吧java對象包裝成更靈巧的API |
語言特有的包裝功能 | 通過實現一種直接加載並解析DSL腳本的程序抽象直接與java集成 |
外部DSL的集成入口
外部DSL的集成模式 | 集成入口 |
---|---|
上下文渠道的字符串操作 | 字符串經過分詞處理被轉化爲宿主語言代碼,如果正則匹配和動態代碼解析 |
XML轉換成可使用的資源 | XML解析器 |
非文本表述 | 非文本表示被轉化成AST,根據應用本身使用的宿主語言生成一顆該語言的具體語法樹 |
DSL中內嵌異質代碼 | 將內嵌代碼作爲回調函數插入其中 |
基於解析器組合子的DSL設計 | 以宿主語言寫成的組合子就是解析外部DSL的規則 |
處理錯誤和異常
待解問題 | DSL設計者的解決之道 |
---|---|
給異常命名 | 異常狀態也是領域抽象。應當一致使用領域語言來表述過程中可能發生的任何異常 |
處理輸入錯誤 | 1. 方法名、對象名或者其他語言主體不存在時給出提示 2. 語法解析器的功用 |
處理異常的業務狀態 | 向用戶提供充分的上下文信息 |
最佳實踐
- 設計內部DSL的時候,應該遵循實現語言的最佳實踐
- Ruby,Groovy等動態語言給與使用者非常大的元編程能力
- 對於像scala這樣的實現語言,靜態類型是良好的幫手
- 對應clojure這類具有編譯時元編程能力的語言,請用宏來自定義語法結構
語法分析基礎設施
- 詞法分析
- 語法分析
- 抽象語法樹
- 代碼生成
語法制導翻譯
- 一套上下文無關語法。它的意義是決定哪些產生式是有效的
- 一套語義規則,作用對象是語法識別的符號的屬性。這些規則在生產語義模型時發揮作用
語法分析器的分類
- 簡單的自頂向下語法分析器
- LL(1)遞歸下降分析器
- LL(k)遞歸下降分析器
- 高級的自頂向下語法分析器
- 遞歸下降回溯分析器: PEG(parsing expression grammar, 解析表達語法)
- 帶中間結果記憶的分析器: Packrat分析器
- 語義謂詞分析器:
- 自底向上語法分析器
- 算符優先分析器
- LR(k)分析器:移進-歸約分析(shift-reduce)
- LR分析器的變體:簡單LR(SLR)、前瞻LR(LALR)、規範LR(canonical LR)