Talk about compiler and parser


會注意到 LLVM 是剛開始在學 XCode 時, 在 build settings 裡出現 Apple LLVM 6.0, 裡面有很多項目, 像是 Code Generation, Language, Modules, Preprocessing, Warning, … etc, 其實不是很了解他的明白. 不過後來在看 台灣軟體產業的失落十年 這本書時, 作者也提到 LLVM, 找了一些資料來讀, 像是 LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例, 我才意會到這東西是了不起的概念.


土法煉鋼

以前做過一個 product 有一段功能是需要 convert COBOL to Java. Code 有一段用 yacc 產生 COBOL parser, 每次看到這段都不知道在做啥 … 只知道 yacc 以前修 unix 時老師有提過 … 反正大概就是 parser 的東西. 那時候 code 的架構很大, 抽象了很多層, 就是練功的過程.

後來自己在寫 test framework 時, 為了讓 test case 的配置檔,也就是 config 更靈活、更有彈性,設計、實作類似 java annotation 的 “語法”, 然後用 python 實作了一個小 parser, 這個 parser 實作以下功能:

  1. config 的資料結構定義,基本上是 key / value 概念,也支援 list,但可讀性沒有 json or yaml 那麼好。
  2. config 包還繼承功能,實際應用是 testcase config 會繼承 testsuite config.
  3. config 繼承包含 overwrite 概念
  4. config 支援 annnotation ,也就是 AOP
  5. annotation 支援 key value, attributes 等概念
  6. config 本身在 test framework 裡面是 DI/IOC 的實作概念。

過程中遇到很多問題, 像是 syntax scanner (LLVM: Implementing a Language ch1 提到的 Lexer), 也就是要檢查整個 code 的語法正確性 / 合法性, 當使用者 code 寫錯了, 要跟使用者說, 錯在哪一行, 錯誤是什麼. 下圖是當時設計時寫的部分 design, 主要是在定義 syntax 的部分:


實作的過程, 想很多很多東西, 整個語法應該是有個結構性 / 相依性 / 參考點, 像 XML Schema 那樣的 meta 定義, 後來才知道有 AST (Abstract Syntax Tree, ch2) 這種概念.

後來前面兩個都做完, 想到應該要可以擴充, 除了 pre-defined 的 keyword, 也要讓使用者可以自訂, 就像 java 只要宣告 @interface 就可以了. 所以整個 parser 又砍掉重練好幾次 (四到五次有吧), 最後因為換工作關係, 沒有繼續完成它.

這是一個有趣的經驗, 雖然是土法煉鋼, 但是過程中也讓我一直在思考, 如何真的做一個有用的東西, 更有效率的解決問題, 另外就是原來 compiler / parser 的背後, 有這麼多學問在.


後記

後來有發現一些工具可以做類似的事情, 像是 DSL, Domain-specific language, Eclipse 3.7 開始有的 xtext, JVM language: groovy 的 DSL (gradle 就是應用案例之一). 這些應用其實就是我當時在做 test framework 時, 後來可以用來改善的工具與方法.

延伸閱讀 (站內)

推薦閱讀


Comments