### Example Go Source File Source: https://github.com/chai2010/go-ast-book/blob/master/ch4/readme.md A simple Go source file demonstrating common top-level declarations such as package, import, type, const, var, and func. This example illustrates the basic structure of a Go program file. ```Go package pkgname import ("a", "b") type SomeType int const PI = 3.14 var Length = 1 func main() {} ``` -------------------------------- ### Go Grouped Constant and Variable Declaration Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch5/readme.md Illustrates how Go supports grouped declarations for variables, contrasting it with individual constant declarations. This example shows a single constant and a group of two variables. ```Go const Pi = 3.14 var ( a int b bool ) ``` -------------------------------- ### Go Classic `for` Loop Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch10/readme.md A basic Go function demonstrating the classic `for` loop structure (`for x; y; z {}`). This example serves as the basis for analyzing the Abstract Syntax Tree (AST) representation of such loops. ```Go func main() { for x; y; z {} } ``` -------------------------------- ### Go: Example of Loading Multiple Packages with Custom Program Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md Illustrates the usage of the custom `Program` struct to load multiple packages with dependencies. It first loads the 'math' package (a leaf package) and then the 'hello' package, which imports 'math', demonstrating the sequential loading required when using a custom importer. ```Go func main() { prog := NewProgram(map[string]string{ "hello": "package main\n\t\t\timport \"math\"\n\t\t\tfunc main() { var _ = 2 * math.Pi }\n\t\t", "math": "package math\n\t\t\tconst Pi = 3.1415926\n\t\t" }) _, _, err := prog.LoadPackage("math") if err != nil { log.Fatal(err) } pkg, f, err := prog.LoadPackage("hello") if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Go Create Simple Identifier with ast.NewIdent Source: https://github.com/chai2010/go-ast-book/blob/master/ch2/readme.md This example demonstrates how to create a simple identifier 'x' using the `ast.NewIdent` function. The `ast.Print` function is then used to display the Abstract Syntax Tree (AST) representation of the newly created identifier, showing its basic structure. ```Go func main() { ast.Print(nil, ast.NewIdent(`x`)) } ``` ```AST Output 0 *ast.Ident { 1 . NamePos: 0 2 . Name: "x" 3 } ``` -------------------------------- ### Go Example: token.Position String Method Output Source: https://github.com/chai2010/go-ast-book/blob/master/ch1/readme.md This Go program demonstrates how the `String()` method of `token.Position` formats location information based on the fields provided. It shows various combinations of `Filename`, `Line`, and `Column` fields, illustrating that `Line` is a mandatory component for a valid position string (otherwise it outputs '-'). The output shows how different combinations of fields result in different string representations: `hello.go:1:2` `hello.go:1` `hello.go` `1:2` `1` `-` ```Go func main() { a := token.Position{Filename: "hello.go", Line: 1, Column: 2} b := token.Position{Filename: "hello.go", Line: 1} c := token.Position{Filename: "hello.go"} d := token.Position{Line: 1, Column: 2} e := token.Position{Line: 1} f := token.Position{Column: 2} fmt.Println(a.String()) fmt.Println(b.String()) fmt.Println(c.String()) fmt.Println(d.String()) fmt.Println(e.String()) fmt.Println(f.String()) } ``` -------------------------------- ### Go Constant Declaration Examples Source: https://github.com/chai2010/go-ast-book/blob/master/ch5/readme.md Demonstrates Go constant declarations, including a weakly typed float constant (Pi) and a strongly typed float64 constant (E), highlighting the difference in type inference and assignment rules. ```Go const Pi = 3.14 const E float64 = 2.71828 ``` -------------------------------- ### Go Simplified `for range` Loop Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch10/readme.md A basic Go function demonstrating a simplified `for range` loop, iterating over a channel (`ch`) without explicitly capturing key or value. This example is used to illustrate the corresponding Abstract Syntax Tree (AST) structure for `range` loops. ```Go func main() { for range ch {} } ``` -------------------------------- ### Go Example: Basic Lexical Analysis with go/scanner Source: https://github.com/chai2010/go-ast-book/blob/master/ch1/readme.md This Go program demonstrates how to perform basic lexical analysis using the `go/scanner` and `go/token` packages. It initializes a `token.FileSet` and `token.File` to manage source code position, then creates and initializes a `scanner.Scanner` with a sample Go code string. The program iterates through the tokens using `s.Scan()` until `token.EOF` is reached, printing each token's position, type, and literal value. The output shows the tokenized form of `println("你好,世界")` as: `hello.go:1:1\tIDENT\t"println"` `hello.go:1:8\t(\t""` `hello.go:1:9\tSTRING\t"\"你好,世界\""` `hello.go:1:26\t)\t""` `hello.go:1:27\t;\t"\n"` ```Go 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) } } ``` -------------------------------- ### Go ANTLR4 CalcParser API Reference Source: https://github.com/chai2010/go-ast-book/blob/master/appendix/b-antlr4/readme.md This section provides the API documentation for the `CalcParser` struct generated by ANTLR4 in Go. It lists the constructor `NewCalcParser` for creating parser instances and key methods like `Expression()` and `Start()` for initiating parsing of specific grammar rules, returning their respective context objects. ```APIDOC package parser // import "." type CalcParser struct { *antlr.BaseParser } func NewCalcParser(input antlr.TokenStream) *CalcParser func (p *CalcParser) Expression() (localctx IExpressionContext) func (p *CalcParser) Expression_Sempred(localctx antlr.RuleContext, predIndex int) bool func (p *CalcParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool func (p *CalcParser) Start() (localctx IStartContext) ``` -------------------------------- ### Go Basic Type Assertion Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch10/readme.md A simple Go function demonstrating a type assertion on a variable `x` to an `int` type (`x.(int)`). This example illustrates the basic syntax and behavior of type assertions, which return the underlying value if successful or panic if the assertion fails. ```Go func main() { x.(int) } ``` -------------------------------- ### Go Multi-Level Pointer Type Declaration Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md This snippet provides a simple Go type declaration for a two-level pointer (`**int`). It serves as an input example to demonstrate how multi-level pointers are represented in the Abstract Syntax Tree (AST). ```Go type IntPtrPtr **int ``` -------------------------------- ### Go: Example of Cross-Package Import Issue Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md A simple Go `main` package demonstrating an import of the `math` package. This code highlights the initial problem encountered when `go/types` attempts to type-check code with external package dependencies without a configured `Importer`. ```Go package main import "math" func main() { var _ = "a" + math.Pi } ``` -------------------------------- ### Go Slice Type Declaration Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md This snippet provides a simple Go type declaration for an integer slice (`[]int`). It serves as an input example to demonstrate how slice types are represented in the Abstract Syntax Tree (AST). ```Go type IntSlice []int ``` -------------------------------- ### Common Go `for` Loop Syntaxes Source: https://github.com/chai2010/go-ast-book/blob/master/ch10/readme.md Illustrates the four primary forms of `for` loops in Go: infinite loops (`for {}`, `for true {}`), the classic C-style loop (`for i := 0; true; i++ {}`), and the `range` loop for iterating over collections (`for i, v := range m {}`). These examples demonstrate the flexibility of Go's single `for` keyword. ```Go for {} for true {} for i := 0; true; i++ {} for i, v := range m {} ``` -------------------------------- ### Go: Parsing Syntax Tree with Semantic Error Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md This Go code demonstrates how the `go/parser` package can successfully parse a syntactically correct Go file into an Abstract Syntax Tree (AST), even if the code contains semantic errors. The example shows an attempt to add a string and an integer, which is syntactically valid but semantically incorrect in Go, highlighting the need for a separate semantic analysis phase. ```Go func main() { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hello.go", src, parser.AllErrors) if err != nil { log.Fatal(err) } ast.Print(fset, f) } const src = `package pkg func hello() { var _ = "a" + 1 } ` ``` -------------------------------- ### Example Go Interface Type with a Single Method Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md A Go interface definition named `IntReader` that specifies a single method, `Read`, which returns an integer. This demonstrates a basic interface contract. ```Go type IntReader interface { Read() int } ``` -------------------------------- ### Example Go Bidirectional Integer Channel Type Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md A simple Go type definition for a bidirectional channel that carries integer values, demonstrating the basic syntax for declaring a channel type alias. ```Go type IntChan chan int ``` -------------------------------- ### Go Multi-Dimensional Array Type Declaration Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md This snippet provides a simple Go type declaration for a two-dimensional integer array (`[1][2]int`). It serves as an input example to demonstrate how multi-dimensional arrays are represented in the Abstract Syntax Tree (AST). ```Go type IntArrayArray [1][2]int ``` -------------------------------- ### Example Go Function Type Definition Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md A Go type definition for a function that takes two integers (`a`, `b`) and returns a boolean, illustrating how function signatures can be aliased as types. ```Go type FuncType func(a, b int) bool ``` -------------------------------- ### Go Single-Dimensional Array Type Declaration Example Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md This snippet provides a simple Go type declaration for a one-dimensional integer array (`[1]int`). It serves as an input example to demonstrate how array types are represented in the Abstract Syntax Tree (AST). ```Go type IntArray [1]int ``` -------------------------------- ### Example Go Struct Type with a Function Field Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md A Go struct definition named `IntReader` that contains a single field `Read`, which is itself a function type returning an integer. This example is used to illustrate the structural similarity with interfaces at the AST level, where both can contain `FieldList` members. ```Go type IntReader struct { Read func() int } ``` -------------------------------- ### Go ANTLR4 CalcListener Interface Definition Source: https://github.com/chai2010/go-ast-book/blob/master/appendix/b-antlr4/readme.md This snippet defines the `CalcListener` interface in Go, which is essential for traversing the parse tree produced by `CalcParser`. It extends `antlr.ParseTreeListener` and includes `Enter` and `Exit` methods for each grammar rule (Start, Number, MulDiv, AddSub), allowing custom logic to be executed at specific points during tree traversal. ```Go // CalcListener is a complete listener for a parse tree produced by CalcParser. type CalcListener interface { antlr.ParseTreeListener EnterStart(c *StartContext) EnterNumber(c *NumberContext) EnterMulDiv(c *MulDivContext) EnterAddSub(c *AddSubContext) ExitStart(c *StartContext) ExitNumber(c *NumberContext) ExitMulDiv(c *MulDivContext) ExitAddSub(c *AddSubContext) } ``` -------------------------------- ### Go: Main Function for Calculator Execution Source: https://github.com/chai2010/go-ast-book/blob/master/appendix/a-goyacc/readme.md This Go snippet defines the `main` function to initiate the calculator's operation. It first constructs a lexical analyzer using `newCalcLexer` from the input string "1+2*3". Subsequently, the `calcParse` syntax parser reads tokens from this lexer, parses the expression, evaluates it, and updates the global `idValueMap` variable during the process. ```Go func main() { calcParse(newCalcLexer([]byte("1+2*3"))) } ``` -------------------------------- ### Parsing a Go File with go/parser.ParseFile Source: https://github.com/chai2010/go-ast-book/blob/master/ch4/readme.md Demonstrates how to use `parser.ParseFile` from the `go/parser` package to parse a Go source string. It initializes a `token.FileSet` and handles potential errors, providing the foundation for AST analysis. ```Go func main() { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hello.go", src, parser.AllErrors) if err != nil { fmt.Println(err) return } ... } const src = `package pkgname import ("a"; "b") type SomeType int const PI = 3.14 var Length = 1 func main() {} ` ``` -------------------------------- ### Go: Initial Program.LoadPackage Method (No Importer) Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md The initial implementation of the `LoadPackage` method for the `Program` struct. It parses a Go source file and performs type checking. Crucially, it sets `types.Config.Importer` to `nil`, meaning it can only successfully load 'leaf' packages that have no external imports. ```Go func (p *Program) LoadPackage(path string) (pkg *types.Package, f *ast.File, err error) { if pkg, ok := p.pkgs[path]; ok { return pkg, p.ast[path], nil } f, err = parser.ParseFile(p.fset, path, p.fs[path], parser.AllErrors) if err != nil { return nil, nil, err } conf := types.Config{Importer: nil} pkg, err = conf.Check(path, p.fset, []*ast.File{f}, nil); if err != nil { return nil, nil, err } p.ast[path] = f p.pkgs[path] = pkg return pkg, f, nil } ``` -------------------------------- ### Go: Using go/importer.Default() for Standard Library Imports Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md Demonstrates how to configure `go/types.Config` to use `importer.Default()`. This approach allows the type checker to correctly resolve and import standard library packages, such as `math`, enabling successful type checking for common dependencies. ```Go // import "go/importer" conf := types.Config{Importer: importer.Default()} pkg, err := conf.Check("hello.go", fset, []*ast.File{f}, nil) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Initialize ANTLR4 Lexer and Parser in Go Source: https://github.com/chai2010/go-ast-book/blob/master/appendix/b-antlr4/readme.md This Go code snippet shows how to initialize the ANTLR4 lexer and parser for a given input string, such as "1+2*3". It utilizes the generated `calc.NewCalcLexer` to create a token stream from the input and `calc.NewCalcParser` to build the syntax tree, preparing for parse tree traversal. ```Go import ( "github.com/antlr/antlr4/runtime/Go/antlr" calc "./calc" ) func main() { lexer := calc.NewCalcLexer(antlr.NewInputStream("1+2*3")) parser := calc.NewCalcParser(antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)) ... } ``` -------------------------------- ### Building Go AST for Variable Declaration Source: https://github.com/chai2010/go-ast-book/blob/master/ch5/readme.md Provides a Go program that parses a simple Go source string containing a variable declaration and then iterates through the AST to print the `token.Token` type of the declaration and the detailed `*ast.ValueSpec` structure. ```Go func main() { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hello.go", src, parser.AllErrors) if err != nil { log.Fatal(err) } for _, decl := range f.Decls { if v, ok := decl.(*ast.GenDecl); ok { fmt.Printf("token: %v\n", v.Tok) for _, spec := range v.Specs { ast.Print(nil, spec) } } } } const src = `package foo var Pi = 3.14 ` ``` -------------------------------- ### Go Constant Declaration Syntax (BNF) Source: https://github.com/chai2010/go-ast-book/blob/master/ch5/readme.md Defines the formal grammar for Go constant declarations, showing how individual constants or grouped constants can be declared, optionally with explicit types. ```Syntax ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) . ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] . IdentifierList = identifier { "," identifier } . ExpressionList = Expression { "," Expression } . ``` -------------------------------- ### Go: Custom Program Struct for Package Management Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md Defines a `Program` struct to manage a collection of Go packages, including their source code, abstract syntax trees (ASTs), and type-checked package objects. The `NewProgram` constructor initializes the necessary maps and a `token.FileSet` for tracking file positions. ```Go type Program struct { fs map[string]string ast map[string]*ast.File pkgs map[string]*types.Package fset *token.FileSet } func NewProgram(fs map[string]string) *Program { return &Program{ fs: fs, ast: make(map[string]*ast.File), pkgs: make(map[string]*types.Package), fset: token.NewFileSet(), } } ``` -------------------------------- ### Extracting Package and Import Names from ast.File Source: https://github.com/chai2010/go-ast-book/blob/master/ch4/readme.md Shows how to access the package name via `f.Name` and iterate through `f.Imports` to print the imported package paths from a parsed `*ast.File` object. This demonstrates basic navigation of the AST for file-level information. ```Go fmt.Println("package:", f.Name) for _, s := range f.Imports { fmt.Println("import:", s.Path.Value) } // Output: // package: pkgname // import: "a" // import: "b" ``` -------------------------------- ### Go AST Print Output for Constant ValueSpec Source: https://github.com/chai2010/go-ast-book/blob/master/ch5/readme.md Shows the detailed Abstract Syntax Tree structure generated by `ast.Print` for the `Pi` and `E` constant declarations. It illustrates how `Names`, `Values`, and `Type` fields within `*ast.ValueSpec` are populated. ```APIDOC 0 *ast.ValueSpec { 1 . Names: []*ast.Ident (len = 1) { 2 . . 0: *ast.Ident { 3 . . . NamePos: 19 4 . . . Name: "Pi" 5 . . . Obj: *ast.Object { 6 . . . . Kind: const 7 . . . . Name: "Pi" 8 . . . . Decl: *(obj @ 0) 9 . . . . Data: 0 10 . . . } 11 . . } 12 . } 13 . Values: []ast.Expr (len = 1) { 14 . . 0: *ast.BasicLit { 15 . . . ValuePos: 24 16 . . . Kind: FLOAT 17 . . . Value: "3.14" 18 . . } 19 . } 20 } 0 *ast.ValueSpec { 1 . Names: []*ast.Ident (len = 1) { 2 . . 0: *ast.Ident { 3 . . . NamePos: 35 4 . . . Name: "E" 5 . . . Obj: *ast.Object { 6 . . . . Kind: const 7 . . . . Name: "E" 8 . . . . Decl: *(obj @ 0) 9 . . . . Data: 0 10 . . . } 11 . . } 12 . } 13 . Type: *ast.Ident { 14 . . NamePos: 37 15 . . Name: "float64" 16 . } 17 . Values: []ast.Expr (len = 1) { 18 . . 0: *ast.BasicLit { 19 . . . ValuePos: 47 20 . . . Kind: FLOAT 21 . . . Value: "2.71828" 22 . . } 23 . } 24 } ``` -------------------------------- ### Go Variable Declaration Syntax (BNF) Source: https://github.com/chai2010/go-ast-book/blob/master/ch5/readme.md Defines the formal grammar for Go variable declarations, which is structurally similar to constant declarations but uses the `var` keyword. ```Syntax VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) . VarSpec = IdentifierList [ [ Type ] "=" ExpressionList ] . IdentifierList = identifier { "," identifier } . ExpressionList = Expression { "," Expression } . ``` -------------------------------- ### Go AST Print Output for Variable ValueSpec Source: https://github.com/chai2010/go-ast-book/blob/master/ch5/readme.md Shows the output of the Go program for building the AST of a variable declaration, including the `token: var` output and the detailed `*ast.ValueSpec` structure for the `Pi` variable. ```APIDOC token: var 0 *ast.ValueSpec { 1 . Names: []*ast.Ident (len = 1) { 2 . . 0: *ast.Ident { 3 . . . NamePos: 17 4 . . . Name: "Pi" 5 . . . Obj: *ast.Object { 6 . . . . Kind: var 7 . . . . Name: "Pi" 8 . . . . Decl: *(obj @ 0) 9 . . . . Data: 0 10 . . . } 11 . . } 12 . } 13 . Values: []ast.Expr (len = 1) { 14 . . 0: *ast.BasicLit { 15 . . . ValuePos: 22 16 . . . Kind: FLOAT 17 . . . Value: "3.14" 18 . . } 19 . } 20 } ``` -------------------------------- ### Go: Program.Import Method (Implementing types.Importer) Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md Implements the `Import` method, making the `Program` struct conform to the `go/types.Importer` interface. This method checks if a package has already been loaded and returns it, otherwise it indicates that the package is not found, preparing the `Program` to act as a custom package resolver. ```Go func (p *Program) Import(path string) (*types.Package, error) { if pkg, ok := p.pkgs[path]; ok { return pkg, nil } return nil, fmt.Errorf("not found: %s", path) } ``` -------------------------------- ### Go Source File Syntax Specification Source: https://github.com/chai2010/go-ast-book/blob/master/ch4/readme.md Defines the top-level syntax elements of a Go source file, including PackageClause, ImportDecl, and TopLevelDecl. This specification outlines how a Go source file is structured from a grammatical perspective. ```APIDOC SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } . PackageClause = "package" PackageName . PackageName = identifier . ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) . ImportSpec = [ "." | PackageName ] ImportPath . ImportPath = string_lit . TopLevelDecl = Declaration | FunctionDecl | MethodDecl . Declaration = ConstDecl | TypeDecl | VarDecl . ``` -------------------------------- ### Go go/scanner.Scanner Public Interface Source: https://github.com/chai2010/go-ast-book/blob/master/ch1/readme.md Defines the public interface of the `scanner.Scanner` type, including its `ErrorCount` field and the `Init` and `Scan` methods. The `Init` method initializes the scanner with a `token.File`, source bytes, an error handler, and a mode. The `Scan` method returns the token's position, token type, and its literal string representation. ```APIDOC type Scanner struct { ErrorCount int } 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, ) ``` -------------------------------- ### Go Interface Type Syntax Definition Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md Formal grammar definition for Go interface types, including method specifications, method names, and signatures, which define the contract an interface fulfills. ```Syntax InterfaceType = "interface" "{" { MethodSpec ";" } "}" . MethodSpec = MethodName Signature | InterfaceTypeName . MethodName = identifier . InterfaceTypeName = TypeName . Signature = Parameters [ Result ] . Result = Parameters | Type . ``` -------------------------------- ### AST Structure for Go Classic `for` Loop Source: https://github.com/chai2010/go-ast-book/blob/master/ch10/readme.md Shows the Abstract Syntax Tree (AST) representation generated by the Go parser for a classic `for` loop (`for x; y; z {}`). It details the `*ast.ForStmt` node and its children, including `Init`, `Cond`, `Post`, and `Body` fields, illustrating how the loop's components are structured in the AST. ```APIDOC 0 *ast.BlockStmt { 1 . Lbrace: 29 2 . List: []ast.Stmt (len = 1) { 3 . . 0: *ast.ForStmt { 4 . . . For: 32 5 . . . Init: *ast.ExprStmt { 6 . . . . X: *ast.Ident { 7 . . . . . NamePos: 36 8 . . . . . Name: "x" 9 . . . . } 10 . . . } 11 . . . Cond: *ast.Ident { 12 . . . . NamePos: 39 13 . . . . Name: "y" 14 . . . } 15 . . . Post: *ast.ExprStmt { 16 . . . . X: *ast.Ident { 17 . . . . . NamePos: 42 18 . . . . . Name: "z" 19 . . . . } 20 . . . } 21 . . . Body: *ast.BlockStmt { 22 . . . . Lbrace: 44 23 . . . . Rbrace: 45 24 . . . } 25 . . } 26 . } 27 . Rbrace: 47 28 } ``` -------------------------------- ### APIDOC: `go/types.Config.Check` Method Signature Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md Documentation for the `Check` method of `go/types.Config`. This method performs semantic analysis and type checking on a Go package's Abstract Syntax Trees (ASTs). It returns a `types.Package` object on success or an error if semantic issues are found. ```APIDOC func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) path: The path of the package to check. fset: The complete file set, used to resolve element positions in the AST to file names and line/column numbers. files: A slice of ASTs corresponding to all files within the package. info: An optional parameter to store analysis results generated during the check process. Returns: A *types.Package object representing the current package's information on success, or an error. ``` -------------------------------- ### Parse Go Single-Level Pointer Type AST Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md This Go program demonstrates parsing a Go source file containing a single-level pointer type (`*int`) using `go/parser`. It then prints the Abstract Syntax Tree (AST) for the type specification, illustrating how `*ast.StarExpr` represents the pointer. ```Go func main() { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hello.go", src, parser.AllErrors) if err != nil { log.Fatal(err) } for _, decl := range f.Decls { ast.Print(nil, decl.(*ast.GenDecl).Specs[0]) } } const src = `package foo type IntPtr *int ` ``` -------------------------------- ### Go: Program.Import Method with Recursive Loading Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md Further refines the `Program.Import` method to enable recursive package loading. If a requested package is not found in the cache, it calls `Program.LoadPackage` to load it, allowing the custom importer to handle nested dependencies automatically during type checking. ```Go func (p *Program) Import(path string) (*types.Package, error) { if pkg, ok := p.pkgs[path]; ok { return pkg, nil } pkg, _, err := p.LoadPackage(path) return pkg, err } ``` -------------------------------- ### Go: Performing Type Checking with `go/types` Package Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md This Go code illustrates the use of the `go/types` package to perform semantic analysis and type checking on an Abstract Syntax Tree (AST). After parsing the file with `go/parser`, the `new(types.Config).Check` method is invoked to identify semantic errors, such as the invalid addition of a string and an integer, which was previously only syntactically parsed. ```Go func main() { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hello.go", src, parser.AllErrors) if err != nil { log.Fatal(err) } pkg, err := new(types.Config).Check("hello.go", fset, []*ast.File{f}, nil) if err != nil { log.Fatal(err) } _ = pkg } const src = `package pkg func hello() { var _ = "a" + 1 } ` ``` -------------------------------- ### Go Pointer Type Grammar Specification Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md Defines the formal grammar for Go pointer types, showing how a pointer is formed by an asterisk followed by a base type. It highlights the recursive nature allowing for multi-level pointers. ```APIDOC PointerType = "*" BaseType . BaseType = Type . Type = TypeName | TypeLit | "(" Type ")" . ... ``` -------------------------------- ### Go Channel Type Syntax Definition Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md Formal grammar definition for Go channel types, specifying the keywords and element type for various channel directions (bidirectional, send-only, receive-only). ```Syntax ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType . ``` -------------------------------- ### AST Representation of Go Single-Level Pointer Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md Shows the Abstract Syntax Tree (AST) output for the `type IntPtr *int` declaration. It illustrates how `IntPtr` is an `*ast.TypeSpec` with its `Type` field being an `*ast.StarExpr`, where `X` points to the base type `int`. ```APIDOC 0 *ast.TypeSpec { 1 . Name: *ast.Ident { 2 . . NamePos: 18 3 . . Name: "IntPtr" 4 . . Obj: *ast.Object { 5 . . . Kind: type 6 . . . Name: "IntPtr" 7 . . . Decl: *(obj @ 0) 8 . . } 9 . } 10 . Assign: 0 11 . Type: *ast.StarExpr { 12 . . Star: 25 13 . . X: *ast.Ident { 14 . . . NamePos: 26 15 . . . Name: "int" 16 . . } 17 . } 18 } ``` -------------------------------- ### Generate Go Parser from ANTLR4 Grammar Source: https://github.com/chai2010/go-ast-book/blob/master/appendix/b-antlr4/readme.md This command demonstrates how to use the ANTLR4 JAR to generate Go language parser code from the `Calc.g4` grammar file. The `-Dlanguage=Go` flag specifies the target language, and `-o calc` directs the output Go code to the `calc` directory, creating the necessary lexer and parser files. ```bash $ java -jar antlr-4.8-complete.jar -Dlanguage=Go -o calc Calc.g4 ``` -------------------------------- ### Go go/token.Position Struct Definition Source: https://github.com/chai2010/go-ast-book/blob/master/ch1/readme.md Defines the `Position` struct from the `go/token` package, which represents detailed source code location information. It includes fields for `Filename`, byte `Offset` (from 0), `Line` number (from 1), and `Column` number (from 1). The `Offset` is used for internal data lookup, while `Line` and `Column` are typically used for display. ```APIDOC type Position struct { Filename string Offset int Line int Column int } ``` -------------------------------- ### AST Representation of Go Multi-Level Pointer Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md Shows the Abstract Syntax Tree (AST) output for the `type IntPtrPtr **int` declaration. It demonstrates the recursive nature of `*ast.StarExpr` where the `X` field of an outer `StarExpr` is another `StarExpr`, forming a chain for multi-level pointers. ```APIDOC 11 . Type: *ast.StarExpr { 12 . . Star: 28 13 . . X: *ast.StarExpr { 14 . . . Star: 29 15 . . . X: *ast.Ident { 16 . . . . NamePos: 30 17 . . . . Name: "int" 18 . . . } 19 . . } 20 . } ``` -------------------------------- ### Generalized Go `for` Loop Patterns Source: https://github.com/chai2010/go-ast-book/blob/master/ch10/readme.md Presents the two generalized patterns for Go's `for` loops: the classic `for x; y; z {}` structure and the `for x, y := range z {}` structure. These patterns encompass all specific `for` loop variations, highlighting the core mechanisms for iteration in Go. ```Go for x; y; z {} for x, y := range z {} ``` -------------------------------- ### Go: Program.LoadPackage Updated to Use Self as Importer Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md An update to the `Program.LoadPackage` method, where `types.Config.Importer` is now set to the `Program` instance itself (`p`). This modification enables the type checker to use the `Program`'s custom `Import` method to resolve and load dependent packages during the type checking process. ```Go func (p *Program) LoadPackage(path string) (pkg *types.Package, f *ast.File, err error) { // ... conf := types.Config{Importer: p} // 用 Program 作为包导入器 pkg, err = conf.Check(path, p.fset, []*ast.File{f}, nil) if err != nil { return nil, nil, err } // ... } ``` -------------------------------- ### Go Function Type Syntax Definition Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md Formal grammar definition for Go function types, detailing the `func` keyword, signature, parameters, and results, which together define a function's type without its name. ```Syntax FunctionType = "func" Signature . Signature = Parameters [ Result ] . Result = Parameters | Type . Parameters = "(" [ ParameterList [ "," ] ] ")" . ParameterList = ParameterDecl { "," ParameterDecl } . ParameterDecl = [ IdentifierList ] [ "..." ] Type . ``` -------------------------------- ### AST Representation of `IntReader` Interface Type Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md The parsed Abstract Syntax Tree (AST) structure for the `IntReader` interface, showing the `ast.InterfaceType` node with its `Methods` list containing the `Read` method, including its parameters and return type, as represented in the AST. ```APIDOC 11 . Type: *ast.InterfaceType { 12 . . Interface: 28 13 . . Methods: *ast.FieldList { 14 . . . Opening: 38 15 . . . List: []*ast.Field (len = 1) { 16 . . . . 0: *ast.Field { 17 . . . . . Names: []*ast.Ident (len = 1) { 18 . . . . . . 0: *ast.Ident { 19 . . . . . . . NamePos: 41 20 . . . . . . . Name: "Read" 21 . . . . . . . Obj: *ast.Object { 22 . . . . . . . . Kind: func 23 . . . . . . . . Name: "Read" 24 . . . . . . . . Decl: *(obj @ 16) 25 . . . . . . . } 26 . . . . . . } 27 . . . . . } 28 . . . . . Type: *ast.FuncType { 29 . . . . . . Func: 0 30 . . . . . . Params: *ast.FieldList { 31 . . . . . . . Opening: 45 32 . . . . . . . Closing: 46 33 . . . . . . } 34 . . . . . . Results: *ast.FieldList { 35 . . . . . . . Opening: 0 36 . . . . . . . List: []*ast.Field (len = 1) { 37 . . . . . . . . 0: *ast.Field { 38 . . . . . . . . . Type: *ast.Ident { 39 . . . . . . . . . . NamePos: 48 40 . . . . . . . . . . Name: "int" 41 . . . . . . . . . } 42 . . . . . . . . } 43 . . . . . . . } 44 . . . . . . . Closing: 0 45 . . . . . . } 46 . . . . . } 47 . . . . } 48 . . . } 49 . . . Closing: 52 50 . . } 51 . . Incomplete: false 52 . } ``` -------------------------------- ### ast.File Structure Definition Source: https://github.com/chai2010/go-ast-book/blob/master/ch4/readme.md Defines the `File` struct from the `go/ast` package, which represents a Go source file's abstract syntax tree. It includes fields for documentation, package information, declarations, scope, imports, unresolved identifiers, and comments. ```APIDOC type File struct { Doc *CommentGroup // associated documentation; or nil Package token.Pos // position of "package" keyword Name *Ident // package name Decls []Decl // top-level declarations; or nil Scope *Scope // package scope (this file only) Imports []*ImportSpec // imports in this file Unresolved []*Ident // unresolved identifiers in this file Comments []*CommentGroup // list of all comments in the source file } ``` -------------------------------- ### Traverse ANTLR4 Parse Tree with Custom Listener in Go Source: https://github.com/chai2010/go-ast-book/blob/master/appendix/b-antlr4/readme.md This Go code demonstrates the final step of traversing the ANTLR4 parse tree to evaluate an expression. It initializes the lexer and parser, creates an instance of the custom `calcListener` (which contains the evaluation logic), and then uses `antlr.NewParseTreeWalker().Walk()` to traverse the tree. After traversal, the final computed result is popped from the listener's internal stack. ```Go func main() { lexer := calc.NewCalcLexer(antlr.NewInputStream("1+2*3")) parser := calc.NewCalcParser(antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)) var l calc.CalcListener = new(calcListener) antlr.NewParseTreeWalker().Walk(l, parser.Start()) fmt.Println(l.(*calcListener).pop()) } ``` -------------------------------- ### Go AST Interface and Struct Type Structures Source: https://github.com/chai2010/go-ast-book/blob/master/ch7/readme.md Definitions of `ast.InterfaceType` and `ast.StructType` structs in Go's `go/ast` package, highlighting their similar structure with `FieldList` for methods and fields respectively, indicating a common underlying AST representation. ```Go type InterfaceType struct { Interface token.Pos // position of "interface" keyword Methods *FieldList // list of methods Incomplete bool // true if (source) methods are missing in the Methods list } type StructType struct { Struct token.Pos // position of "struct" keyword Fields *FieldList // list of field declarations Incomplete bool // true if (source) fields are missing in the Fields list } ``` -------------------------------- ### AST Structure for Go `for range` Loop Source: https://github.com/chai2010/go-ast-book/blob/master/ch10/readme.md Shows the Abstract Syntax Tree (AST) representation generated by the Go parser for a simplified `for range` loop (`for range ch {}`). It details the `*ast.RangeStmt` node and its children, including the expression being ranged over (`X`) and the loop body (`Body`), demonstrating how `range` loops are structured in the AST. ```APIDOC 0 *ast.BlockStmt { 1 . Lbrace: 29 2 . List: []ast.Stmt (len = 1) { 3 . . 0: *ast.RangeStmt { 4 . . . For: 32 5 . . . TokPos: 0 6 . . . Tok: ILLEGAL 7 . . . X: *ast.Ident { 8 . . . . NamePos: 42 9 . . . . Name: "ch" 10 . . . } 11 . . . Body: *ast.BlockStmt { 12 . . . . Lbrace: 45 13 . . . . Rbrace: 46 14 . . . } 15 . . } 16 . } 17 . Rbrace: 48 18 } ``` -------------------------------- ### APIDOC: Go types.Config and Importer Interface Source: https://github.com/chai2010/go-ast-book/blob/master/ch11/readme.md API definition for `go/types.Config` struct, which contains the `Importer` interface, and the `types.Importer` interface itself. The `Import` method is essential for `go/types` to resolve and load information about dependent packages during type checking. ```APIDOC type Config struct { Importer Importer } type Importer interface { Import(path string) (*Package, error) } ```