这是我参与「第五届青训营 」伴学笔记创作活动的第 17 天
2.1 前言
上期笔记我们已经铺叙了有关编译逻辑层面的四个阶段(详情见《一切从编译开始》),本期笔记我们继续探讨关于 Go 语言的词法分析和语法分析。
2.2 词法分析
2.2.1 关于 Token
Token
中文翻译为标记,是一个字符串,也是构成源代码的最小单位,从输入字符流中生成标记的过程叫作标记化(tokenization
),在这个过程中,词法分析器还会对标记进行分类。编译器会从左到右扫描我们的源代码,将其中的字符流分割成一个一个的Token
。
2.2.2 Go 词法分析的实现
Go 语言的词法分析是通过cmd/compile/internal/syntax.scanner
结构体实现的,这个结构体会持有当前扫描的数据源文件、启用的模式和当前被扫描到的Token
。
type scanner struct {
source
mode uint
nlsemi bool
// current token, valid after calling next()
line, col uint
blank bool // line is blank up to col
tok token
lit string // valid if tok is _Name, _Literal, or _Semi ("semicolon", "newline", or "EOF"); may be malformed if bad is true
bad bool // valid if tok is _Literal, true if a syntax error occurred, lit may be malformed
kind LitKind // valid if tok is _Literal
op Operator // valid if tok is _Operator, _AssignOp, or _IncOp
prec int // valid if tok is _Operator, _AssignOp, or _IncOp
}
Go 语言中支持的全部Token
类型都在src/cmd/compile/internal/syntax/tokens.go
文件中定义了,所有的Token
类型都是正整数,常见Token
定义如:操作符、括号和关键字等。
const (
_ token = iota
_EOF // EOF
// operators and operations
_Operator // op
...
// delimiters
_Lparen // (
_Lbrack // [
...
// keywords
_Break // break
...
_Type // type
_Var // var
tokenCount //
)
Go 语言中定义的Token将语言中的元素分为了四个类型,分别是名称和字面量、操作符、分隔符、和关键字,其词法分析主要由 cmd/compile/internal/syntax.scanner
结构体中的cmd/compile/internal/syntax.scanner.next
方法驱动,而驱动主体是一个switch/case
结构,在for
循环中不断获取最新字符,并通过cmd/compile/internal/syntax.source.nextch
方法追加到 cmd/compile/internal/syntax.scanner
持有的缓冲区中。
func (s *scanner) next() {
...
s.stop()
startLine, startCol := s.pos()
for s.ch == ' ' || s.ch == '\t' || s.ch == '\n' && !nlsemi || s.ch == '\r' {
s.nextch()
}
s.line, s.col = s.pos()
s.blank = s.line > startLine || startCol == colbase
s.start()
if isLetter(s.ch) || s.ch >= utf8.RuneSelf && s.atIdentChar(true) {
s.nextch()
s.ident()
return
}
switch s.ch {
case -1:
s.tok = _EOF
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
s.number(false) //整数匹配
...
}
}
值得一提的是,早期 Go 语言其实也用过 lex 来生成词法解析器,但后来还是使用 Go 来实现了词法分析器,用自己写的词法分析器来解析自己。
词法分析到此告一段落,过度深入了解无异于囫囵吞枣,语法分析将在下期笔记中探究。