AntzScript
🎓 The language executed in the Antz system.
基於以實現的內置vim,接下來需要實現Antz系統中內置語言AntzScript。
| vim |
|---|
![]() |
一、概述
1. 解釋器與編譯器
1.1 解釋器
解釋器根據程序中的算法執行運算。簡單地說,它是一種用於執行程序的軟件。
1.2 編譯器
編譯器能將某種語言寫成的程序轉換為另一種語言的程序。通常它會將源程序轉換為機器語言程序。編譯器轉換程序的行為稱為編譯,轉換前的程序稱為源程序。
- Java虛擬機為了提高性能,會在執行過程中通過編譯器將一部分Java二進制代碼直接轉換為機器語言使用。
過去的編譯器編譯過程非常費時,不過由於編譯后實際執行的是機器語言,因此執行速度很快。而解釋器,會在程序輸入的同時立即執行,執行速度較慢。這就是兩者的基本區別。
在為Antz制作內置腳本語言時,因為是直接執行,處理器屬於解釋器,不過,為了提高性能,該解釋器內部將采用編譯器。
基本流程如下
![]() |
![]() |
2. Token
語言處理器的第一個組成部分是詞法分析器(lexer)。程序的源代碼最初只是一長串字符串,這樣的字符串很難處理,語言處理器通常會首先將字符串中的字符以解析單元分組,切割成多個Token,這就是詞法分析。
| 解析結果 |
|---|
![]() |
![]() |
Token類中需要對源代碼分割成最小單元,並解析出變量類型,數值量,符號,標識符等
| Token |
|---|
![]() |
| Token中k代表單元含義,lexeme代表其在代碼中的內容。kindMap是一個提前預置關系轉換符表。在需要添加其他關鍵字時可以直接在KindMap中添加。 |
![]() |
詞法解析器的實現方法有手工構造法和正則表達式的方法。
| 手工構造法-狀態圖 |
|---|
![]() |
這種方法較為復雜,需要大量的代碼,而正則表達式的方法較為便捷。
二、實現詞法解析
借助正則表達式庫能簡單地實現詞法分析器。下表列出的記號在大多數情況下都能使用。例如,.*\.java指的是以.java結束的任意長度的字符串模式。.*\.由兩部分組成,.*表示由任意字符組成的任意長度的字符串模式,\.表示與句點字符相匹配的字符串模式。(java|javax)\..*則表示由java.或javax.起始的任意長度的字符串模式。
| 元字符 | 含義 |
|---|---|
| . | 與任意字符匹配 |
| [0-9] | 與0至9中的某個數字匹配 |
| [^0-9] | 與0至9這些數字之外的的某個字符匹配 |
| pattern* | 模式pattern至少重復出現0次 |
| pattern+ | 模式pattern至少重復出現1次 |
| pattern? | 模式pattern出現0次或1次 |
| pattern1 | pattern2 |
| () | 將括號內視為一個完整的模式 |
| \c | 與單個字符c(元字符*或.等)匹配 |
整型字面量的匹配
[0-9]+
標識符的匹配
[A-Z_a-z][A-Z_a-z0-9]*
- 以字母、下划線開頭,之后僅包含有字母、數字、下划線的就是標識符的定義規則。
[A-Z_a-z][A-Z_a-z0-9]*|==|<=|>=|&&|\|\||\p{Punct}
最后的\p{Punct}表示與任意一個符號字符匹配。模式\|\|將會匹配||。由於|是正則表達式的元字符,因此在使用時必須添加反斜線轉義。
最后需要定義的是字符串字面量。由於不得不處理各種轉義字符,字符串字面量的定義略微復雜。
"(\\"|\\\\|\\n|[^"])*"
首先,從整體上看,這是一個"(pattern)*"形式的模式,即雙引號內是一個與pattern重復出現至少0次的結果匹配的字符串。其中,模式pattern與\"、\\、\n匹配,同時也與除"之外任意一個字符匹配。
所以我們可以得到一個下圖的匹配規則regexPat。
ArrayList<Token> tokens是詞法解析器Lexer中已解析的Token。
源碼source作為參數傳入Lexer的add方法中。
在創建Token時,單元作為構造函數的參數。同時變量,數字值等單元我們無法通過KindMap類來判斷k值,所以需要在這里判斷。
| 判斷是否是變量類型 |
|---|
![]() |
| 判斷是否是數值類型 |
|---|
![]() |
| 判斷是否是字符串類型 |
|---|
![]() |
三、效果
| 測試代碼 |
|---|
![]() |
| Token解析 |
|---|
![]() |
![]() |
將源代碼轉換為了相應的Token單元,這就是詞法解析的主要工作了。
接下來按照源代碼獲得轉換后的直譯代碼。
| 效果圖 |
|---|
![]() |















