GO代码
-
go后缀文件
//go 编译器 cmd/compile/internal/gc/main.go 1.通过词法分析获取所有程序token 2.通过语法分析生成抽象语法树(AST) 3.遍历检查抽象语法树,检查过程中改替换部分代码为内建函数 4.编译检查通过抽象语法树,生成中间代码。 6.执行优化中间代码并生成机器码
-
词法分析
由关键字/标识符/数字/字符串/字符/注释组成
//go程序由关键字/标识符/常量/字符串/符号/注释 import fmt fmt.Println("Hello, World!",1) //import 关键字 //fmt 标识符 //. ,()字符 //"Hello, World!" 字符串 //1 数字
cmd/compile/internal/syntax/scanner.go // 词法扫描器
type scanner struct { source mode uint nlsemi bool // if set '\n' and EOF translate to ';' // 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 }
cmd/compile/internal/syntax/tokens.go //词法扫描的token
const ( _ token = iota _EOF // EOF // names and literals _Name // name _Literal // literal // operators and operations // _Operator is excluding '*' (_Star) _Operator // op _AssignOp // op= _IncOp // opop _Assign // = _Define // := _Arrow // <- _Star // * // delimiters _Lparen // ( _Lbrack // [ _Lbrace // { _Rparen // ) _Rbrack // ] _Rbrace // } _Comma // , _Semi // ; _Colon // : _Dot // . _DotDotDot // ... // keywords 25个关键字 _Break // break _Case // case _Chan // chan _Const // const _Continue // continue _Default // default _Defer // defer _Else // else _Fallthrough // fallthrough _For // for _Func // func _Go // go _Goto // goto _If // if _Import // import _Interface // interface _Map // map _Package // package _Range // range _Return // return _Select // select _Struct // struct _Switch // switch _Type // type _Var // var // empty line comment to exclude it from .String tokenCount // )
-
语法分析
cmd/compile/internal/syntax/parser.go
/* package (声明包) //必须第一行 var(声明变量) const(声明常量) type(声明类型) func(声明函数) */ // SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } . func (p *parser) fileOrNil() *File // ImportSpec = [ "." | PackageName ] ImportPath . // ImportPath = string_lit . func (p *parser) importDecl(group *Group) Decl // ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] . func (p *parser) constDecl(group *Group) Decl // TypeSpec = identifier [ "=" ] Type . func (p *parser) typeDecl(group *Group) Decl // VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) . func (p *parser) varDecl(group *Group) Decl // FunctionDecl = "func" FunctionName ( Function | Signature ) . // FunctionName = identifier . // Function = Signature FunctionBody . // MethodDecl = "func" Receiver MethodName ( Function | Signature ) . // Receiver = Parameters . func (p *parser) funcDeclOrNil() *FuncDecl ....
行分隔符
程序结束不需要
注释
// 单行注释
/*
我是多行注释
*/
关键字
//25 关键字
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
//37 保留字
Constants: true false iota nil
Types: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
Functions: make len cap new append copy close delete
complex real imag
panic recover
标识符
Go的函数、变量、常量、自定义类型、包(package)
的命名方式遵循以下规则:
1. 首字符可以是任意的Unicode字符或者下划线
2. 剩余字符可以是Unicode字符、下划线、数字
3. 字符长度不限
包管理
-
go文件必须在第一行声明包。
-
同一个目录下只能属于一个包名,通常情况下包名就是目录名。
-
同目录下go文件之间调用不需要引入包。
-
main方法所在包名必须为main才可以正常运行。
//定义包名 package 包名 //引入单个包 import "xxxx" //包名格式为目标go文件所在文件夹的相对目录。 //引入多个包 import ( "xxx1" //普通引用 a "xxx2" //重命名包 . "xxx3" //不带包前缀 _ "xxx" //仅调用包init函数 )
可见性
1. 声明在函数内部,是函数的本地值,类似private
2. 声明在函数外部,是对当前包可见(包内所有.go文件都可见)的全局值,类似protect
3. 声明在函数外部且首字母大写是所有包可见的全局值,类似public