Go AST Book
repository·master·Indexed 26 days ago
https://github.com/chai2010/go-ast-bookA technical guide on using Go's standard library (go/ast, go/token) to analyze and manipulate Go source code via its Abstract Syntax Tree. The documentation covers lexical analysis with scanner.Scanner, managing source files with FileSet, and understanding AST structures like BlockStmt and ExprStmt. It also includes appendices on generating parsers and lexers using goyacc, flex, and ANTLR4.
What's inside go-ast-book
- Chapter 14 introduces 'Ao Language' (凹语言), a minimal subset of a programming language created by pruning the existing Go abstract syntax tree (AST). This chapter demonstrates the step-by-step process of implementing an interpreter for this subset, synthesizing concepts covered in previous chapters of the book.
Overview of Semantic Information in Go AST
masterSemantic information in Go involves determining the types and values of objects based on their names and analyzing the types and values of expressions. This process is primarily handled by thego/typespackage. Thego/typespackage was developed by Robert Griesemer and is used for performing type checking within the Go ecosystem.Overview of SSA (Static Single Assignment) form in Go
masterChapter 13 explores the process of converting Go language AST (Abstract Syntax Tree) into SSA (Static Single Assignment) form. It covers how to perform interpreted execution using the SSA form and provides an overview of the logical relationships between the important data structures within thessapackage.Overview of LLVM Introduction (Chapter 15)
masterChapter 15 provides a high-level introduction to LLVM. Rather than focusing on deep compiler theory or complex internal implementations, the chapter focuses on two practical aspects:
- What LLVM can do (capabilities and use cases).
- How to use LLVM (practical application).
Note: Due to copyright restrictions, the full content of this chapter is not available in this repository. To access the complete material, you must refer to the physical/digital book.
Overview of Go AST Book
masterThe Go AST Book (formerly Go Syntax Tree Introduction) is a technical guide focused on the Go Abstract Syntax Tree (AST). It explores the semantic representation of Go source files using the standard library's
go/astandgo/tokenpackages. The book provides practical knowledge for building tools similar togo fmtandgo docby analyzing Go programs through their syntax tree structures.Key Resources:
- Online Reading: https://chai2010.cn/go-ast-book
- Related Project (wa-lang): https://github.com/wa-lang/wa (A language designed for WebAssembly)
- Related Project (waBook): https://github.com/wa-lang/wabook (A Markdown ebook builder implemented in pure Go)
Overview of LLVM Instance Chapter
masterChapter 16 provides a comprehensive example of translating a Go Abstract Syntax Tree (AST) into LLVM Intermediate Representation (LLVM-IR) and subsequently generating an executable program. This builds upon previous sections that covered writing LLVM-IR programs and using LLVM tools to compile them.Manage source files with FileSet and File
masterTo perform lexical analysis on source code, use
token.FileSetandtoken.Fileobjects to manage file positions and collections.token.FileSet: Represents a collection of files. It manages a global position space usingtoken.Pos(an integer type representing an index in the underlying array).token.File: Represents a single file within aFileSet. It contains the filename, abaseposition, and asize.
To create a
Fileobject, you must use theAddFilemethod of aFileSetinstance. You cannot construct aFiledirectly.Understand Go function and method syntax in AST
masterIn the Go AST, functions and methods are represented by the
*ast.FuncDecltype. A method is essentially a function with aReceiver.Grammar Rules:
FunctionDecl:func+MethodName+Signature+[FunctionBody]MethodDecl:func+Receiver+MethodName+Signature+[FunctionBody]
Key distinction: The function signature (type) includes only the input parameters and return values. The function name and the method receiver are not part of the function signature.
Understand Go Composite Expressions Syntax
masterComposite expressions in Go are formed by combining operands with high-order operators. The syntax for
PrimaryExprincludes:- Selector:
.identifier (e.g.,x.y) - Index:
[Expression](e.g.,x[y]) - Slice:
[[ Expression ]:[ Expression ]]or[[ Expression ]:Expression:Expression](e.g.,x[1:2:3]) - Type Assertion:
.(Type)(e.g.,x.(y)) - Arguments (Function Calls/Conversions):
([ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ])(e.g.,int(x)orf(x, y))
In the AST, many of these are parsed based on structure before the semantic meaning (like whether a name is a type or a function) is fully resolved.
- Selector:
Understand Basic Literals in Go AST
masterIn Go, Basic Literals are values directly represented in code (e.g.,
2inx+2*y). The Go specification defines basic literals as integers, floating-point numbers, complex numbers, characters, and strings.Note that while
trueandfalseare treated as predefined literal types by users, they are technically built-in boolean identifiers in the Go specification. In thego/tokenpackage, basic literals are represented by specific tokens betweenliteral_begandliteral_end.Configure package importing for cross-package type checking
masterWhen performing type checking on code that imports other packages,
types.Configneeds anImporterto resolve dependencies. Without an importer,Checkwill fail with an error likecould not import <package_name> (Config.Importer not installed).Using the default importer
For standard library packages, use
go/importerto provide the default implementation:import "go/importer" import "go/types" // ... conf := types.Config{Importer: importer.Default()} pkg, err := conf.Check("hello.go", fset, []*ast.File{f}, nil)Implementing a custom Importer
To handle custom package structures or manual loading, implement the
types.Importerinterface:type Importer interface { Import(path string) (*Package, error) }Scan tokens using scanner.Scanner
masterThe
go/scannerpackage provides theScannertype to perform lexical analysis.To use it:
- Create a
token.FileSetusingtoken.NewFileSet(). - Add your source code to the file set using
fset.AddFile(filename, base, len(src)). - Initialize the scanner with
s.Init(file, src, err, mode). - Call
s.Scan()in a loop until it returnstoken.EOF.
Use
fset.Position(pos)to convert the returnedtoken.Posinto a human-readabletoken.Position(filename, line, and column).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) } }- Create a