- 用Go語言自制解釋器
- (德)索斯藤·鮑爾
- 1026字
- 2022-06-17 10:50:31
1.2 定義詞法單元
首先要做的是定義詞法分析器輸出的詞法單元。這里先定義少量的詞法單元,之后在擴展詞法分析器時再添加更多的定義。
第一次要解析的Monkey語言代碼如下所示:
let five = 5;
let ten = 10;
let add = fn(x, y) {
x + y;
};
let result = add(five, ten);
來詳細看看,這個例子中包含哪些類型的詞法單元。首先,有5
和10
這樣的數字,這很明顯;之后是x
、y
、add
和result
這樣的變量名。最后Monkey語言中還有一些單詞,它們既不是數字也不是變量名,例如let
和fn
。當然,還有很多特殊字符,如(
、)
、{
、}
、=
、,
、;
。
這些數字都是整數,將按字面量處理,并賦予其一個單獨的類型。在詞法分析器或語法分析器中,數字的值是5
還是10
并不重要,只要知道它是一個數字就行。變量名也是如此,都統一用作標識符。除此之外還有一些單詞,看起來像標識符但實際上不是,這些稱為關鍵字,也是Monkey語言的一部分。后面在語法分析階段遇到let
或fn
這樣的關鍵字時,都會特殊處理,所以它們不能與標識符歸為一類。最后的特殊字符也會單獨列出來,其中每個特殊字符都會有相應的處理方式,例如在源代碼中,括號會對代碼的含義產生很大影響。
基于這些分析,現在來定義Token
數據結構。它需要哪些字段呢?正如剛剛看到的,肯定需要一個類型屬性,這樣就可以區分“整數”和“右括號”這樣不同的詞法單元。然后還需要一個字段用于保存詞法單元的字面量,以便后續步驟復用,比如對于表示數字的詞法單元,這個字段能記錄5
或10
這樣的信息。
新建一個token
包,以便定義Token
結構和TokenType
類型:
// token/token.go
package token
type TokenType string
type Token struct {
Type TokenType
Literal string
}
TokenType
類型定義成了字符串,這樣我們就可以使用各種TokenType
值,而根據TokenType
值能區分不同類型的詞法單元。使用字符串對調試也有幫助,會讓調試更容易,而無須再使用許多樣板和輔助函數,只需打印一個字符串即可。當然,與使用int
或byte
類型相比,使用字符串會導致程序在性能上有損失。但對于本書而言,使用字符串完全沒有問題。
從剛剛的分析中可以看到,Monkey語言中的詞法單元類型并不多。這意味著可以將所有的TokenType
都定義為常量,所以在上面的代碼中可以再添加以下內容:
// token/token.go
const (
ILLEGAL = "ILLEGAL"
EOF = "EOF"
// 標識符+字面量
IDENT = "IDENT" // add, foobar, x, y, ...
INT = "INT" // 1343456
// 運算符
ASSIGN = "="
PLUS = "+"
// 分隔符
COMMA = ","
SEMICOLON = ";"
LPAREN = "("
RPAREN = ")"
LBRACE = "{"
RBRACE = "}"
// 關鍵字
FUNCTION = "FUNCTION"
LET = "LET"
)
如你所見,上面的代碼中還出現了ILLEGAL
和EOF
這兩種特殊類型。這兩種類型在之前的示例中并沒有遇到,卻是必不可少的。ILLEGAL
表示遇到未知的詞法單元或字符,EOF
則表示文件結尾(End Of File),用于通知后續章節會介紹的語法分析器停機。
目前一切順利,下面準備開始編寫詞法分析器。
- Mastering Concurrency Programming with Java 8
- C程序設計簡明教程(第二版)
- CockroachDB權威指南
- JavaScript修煉之道
- Android開發精要
- 看透JavaScript:原理、方法與實踐
- Learning Neo4j 3.x(Second Edition)
- 算法訓練營:提高篇(全彩版)
- JavaCAPS基礎、應用與案例
- 軟件品質之完美管理:實戰經典
- Raspberry Pi Home Automation with Arduino(Second Edition)
- C語言程序設計
- 用案例學Java Web整合開發
- 時空數據建模及其應用
- Learning Modular Java Programming