編譯技術是一門龐大的學科,我們無法對其做完善的講解。但不同用途的編譯器或編譯技術的難度可能相差很大,對知識的掌握要求也會相差很多。如果你要實現諸如 C、JavaScript 這類通用用途語言(general purpose language),那么就需要掌握較多編譯技術知識。例如,理解上下文無關文法,使用巴科斯范式(BNF),擴展巴科斯范式(EBNF)書寫語法規則,完成語法推導,理解和消除左遞歸,遞歸下降算法,甚至類型系統方面的知識等。但作為前端工程師,我們應用編譯技術的場景通常是:表格、報表中的自定義公式計算器,設計一種領域特定語言(DSL)等。其中,實現公式計算器甚至只涉及編譯前端技術,而領域特定語言根據其具體使用場景和目標平臺的不同,難度會有所不同。Vue.js 的模板和 JSX 都屬于領域特定語言,它們的實現難度屬于中、低級別,只要掌握基本的編譯技術理論即可實現這些功能。
1、模板 DSL 的編譯器
編譯器其實只是一段程序,它用來將“一種語言 A”翻譯成“另外一種語言 B”。其中,語言 A 通常叫作源代碼(source code),語言 B 通常叫作目標代碼(object code 或 target code)。編譯器將源代碼翻譯為目標代碼的過程叫作編譯(compile)。完整的編譯過程通常包含詞法分析、語法分析、語義分析、中間代碼生成、優化、目標代碼生成等步驟,如下圖所示:
可以看到,整個編譯過程分為編譯前端和編譯后端。編譯前端包含詞法分析、語法分析和語義分析,它通常與目標平臺無關,僅負責分析源代碼。編譯后端則通常與目標平臺有關,編譯后端涉及中間代碼生成和優化以及目標代碼生成。但是,編譯后端并不一定會包含中間代碼生成和優化這兩個環節,這取決于具體的場景和實現。中間代碼生成和優化這兩個環節有時也叫“中端”。