1.4 解析詞法單元
Go語言標準庫go/scanner
包提供了Scanner
來實現詞法單元掃描,它在FileSet
和File
抽象文件集合的基礎上進行詞法分析。
scanner.Scanner
的公開接口定義如下:
type Scanner struct {
// public state - ok to modify
ErrorCount int // number of errors encountered
// Has unexported fields
}
func (s *Scanner) Init(
file *token.File, src []byte,
err ErrorHandler, mode Mode,
)
func (s *Scanner) Scan() (
pos token.Pos, tok token.Token, lit string,
)
Init
方法用于初始化掃描器,其中file
參數表示當前的文件(不包含代碼數據),src
參數表示要分析的代碼,err
參數表示用戶自定義的錯誤處理函數,mode
參數可以控制是否掃描注釋部分。
Scan
方法掃描一個詞法單元,3個返回值分別表示詞法單元的位置、詞法單元的值和詞法單元的文本表示。
要構造一個簡單的詞法掃描器測試程序,首先要構造Init
方法的第一個參數所需的File
對象。但是,File
對象沒有公開的構造函數,只能通過FileSet
的AddFile
方法間接構造File
對象。
下面是一個簡單的詞法分析程序:
package main
import (
"fmt"
"go/scanner"
"go/token"
)
func main() {
var src = []byte(`println("你好,世界")`)
var fset = token.NewFileSet()
var file = fset.AddFile("hello.go", fset.Base(), len(src))
var s scanner.Scanner
s.Init(file, src, nil, scanner.ScanComments)
for {
pos, tok, lit := s.Scan()
if tok == token.EOF {
break
}
fmt.Printf("%s\t%s\t%q\n", fset.Position(pos), tok, lit)
}
}
其中,src
是要分析的代碼字符串。
首先通過token.NewFileSet
方法創建一個文件集。這是因為詞法單元的位置信息必須通過文件集定位,并且需要通過文件集創建掃描器的Init
方法所需的file
參數。
然后調用fset.AddFile
方法向fset
文件集添加一個新的文件,文件名為hello.go,文件的長度就是要分析的代碼src
的長度。
接著創建scanner.Scanner
對象,并且調用Init
方法初始化掃描器。Init
方法的第一個參數file
表示剛剛添加到fset
的文件對象,第二個參數src
表示要分析的代碼,第三個參數nil
表示沒有自定義的錯誤處理函數,最后的scanner.ScanComments
參數表示不忽略注釋。
因為要解析的代碼中有多個詞法單元,所以我們在一個循環中調用s.Scan
方法依次解析每個詞法單元。如果返回的是token.EOF
,則表示掃描到了文件末尾,否則輸出掃描返回的結果。輸出前,我們需要將掃描器返回的pos
參數轉換為更詳細的帶文件名和行列號的位置信息,可以通過fset.Position(pos)
方法完成。
運行以上程序的輸出結果如下:
hello.go:1:1 IDENT "println"
hello.go:1:8 ( ""
hello.go:1:9 STRING "\"你好,世界\""
hello.go:1:26 ) ""
hello.go:1:27 ; "\n"
輸出結果的第一列表示詞法單元所在的文件和行列號,中間一列表示詞法單元的枚舉值,最后一列表示詞法單元在源文件中的原始內容。
- Spring 5企業級開發實戰
- 從學徒到高手:汽車電路識圖、故障檢測與維修技能全圖解
- PLC編程及應用實戰
- Android 應用案例開發大全(第3版)
- AutoCAD VBA參數化繪圖程序開發與實戰編碼
- JavaScript:Moving to ES2015
- Node.js全程實例
- Getting Started with Gulp
- 從Excel到Python數據分析:Pandas、xlwings、openpyxl、Matplotlib的交互與應用
- ActionScript 3.0從入門到精通(視頻實戰版)
- Learning WordPress REST API
- Web前端測試與集成:Jasmine/Selenium/Protractor/Jenkins的最佳實踐
- 軟件開發中的決策:權衡與取舍
- Java EE框架開發技術與案例教程
- R語言編程:基于tidyverse