mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile/internal/syntax: fast Go syntax trees, initial commit.
Syntax tree nodes, scanner, parser, basic printers. Builds syntax trees for entire Go std lib at a rate of ~1.8M lines/s in warmed up state (MacMini, 2.3 GHz Intel Core i7, 8GB RAM): $ go test -run StdLib -fast parsed 1074617 lines (2832 files) in 579.66364ms (1853863 lines/s) allocated 282.212Mb (486.854Mb/s) PASS Change-Id: Ie26d9a7bf4e5ff07457aedfcc9b89f0eba72ae3f Reviewed-on: https://go-review.googlesource.com/27195 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
3b967be421
commit
c8683ff797
13 changed files with 5354 additions and 0 deletions
425
src/cmd/compile/internal/syntax/nodes.go
Normal file
425
src/cmd/compile/internal/syntax/nodes.go
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package syntax
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Nodes
|
||||
|
||||
type Node interface {
|
||||
aNode()
|
||||
}
|
||||
|
||||
type node struct {
|
||||
doc *Comment // nil means no comment(s) attached
|
||||
pos uint32
|
||||
line uint32
|
||||
}
|
||||
|
||||
func (*node) aNode() {}
|
||||
|
||||
func (n *node) init(p *parser) {
|
||||
n.pos = uint32(p.pos)
|
||||
n.line = uint32(p.line)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Files
|
||||
|
||||
type File struct {
|
||||
PkgName *Name
|
||||
DeclList []Decl
|
||||
Pragmas []Pragma
|
||||
Lines int
|
||||
node
|
||||
}
|
||||
|
||||
type Pragma struct {
|
||||
Line int
|
||||
Text string
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Declarations
|
||||
|
||||
type (
|
||||
Decl interface {
|
||||
Node
|
||||
aDecl()
|
||||
}
|
||||
|
||||
ImportDecl struct {
|
||||
LocalPkgName *Name // including "."; nil means no rename present
|
||||
Path *BasicLit
|
||||
Group *Group // nil means not part of a group
|
||||
decl
|
||||
}
|
||||
|
||||
ConstDecl struct {
|
||||
NameList []*Name
|
||||
Type Expr // nil means no type
|
||||
Values Expr // nil means no values
|
||||
Group *Group // nil means not part of a group
|
||||
decl
|
||||
}
|
||||
|
||||
TypeDecl struct {
|
||||
Name *Name
|
||||
Type Expr
|
||||
Group *Group // nil means not part of a group
|
||||
decl
|
||||
}
|
||||
|
||||
VarDecl struct {
|
||||
NameList []*Name
|
||||
Type Expr // nil means no type
|
||||
Values Expr // nil means no values
|
||||
Group *Group // nil means not part of a group
|
||||
decl
|
||||
}
|
||||
|
||||
FuncDecl struct {
|
||||
Attr map[string]bool // go:attr map
|
||||
Recv *Field // nil means regular function
|
||||
Name *Name
|
||||
Type *FuncType
|
||||
Body []Stmt // nil means no body (forward declaration)
|
||||
decl
|
||||
}
|
||||
)
|
||||
|
||||
type decl struct{ node }
|
||||
|
||||
func (*decl) aDecl() {}
|
||||
|
||||
// All declarations belonging to the same group point to the same Group node.
|
||||
type Group struct {
|
||||
dummy int // not empty so we are guaranteed different Group instances
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Expressions
|
||||
|
||||
type (
|
||||
Expr interface {
|
||||
Node
|
||||
aExpr()
|
||||
}
|
||||
|
||||
// Value
|
||||
Name struct {
|
||||
Value string
|
||||
expr
|
||||
}
|
||||
|
||||
// Value
|
||||
BasicLit struct {
|
||||
Value string
|
||||
Kind LitKind
|
||||
expr
|
||||
}
|
||||
|
||||
// Type { ElemList[0], ElemList[1], ... }
|
||||
CompositeLit struct {
|
||||
Type Expr // nil means no literal type
|
||||
ElemList []Expr
|
||||
NKeys int // number of elements with keys
|
||||
expr
|
||||
}
|
||||
|
||||
// Key: Value
|
||||
KeyValueExpr struct {
|
||||
Key, Value Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// func Type { Body }
|
||||
FuncLit struct {
|
||||
Type *FuncType
|
||||
Body []Stmt
|
||||
expr
|
||||
}
|
||||
|
||||
// (X)
|
||||
ParenExpr struct {
|
||||
X Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// X.Sel
|
||||
SelectorExpr struct {
|
||||
X Expr
|
||||
Sel *Name
|
||||
expr
|
||||
}
|
||||
|
||||
// X[Index]
|
||||
IndexExpr struct {
|
||||
X Expr
|
||||
Index Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// X[Index[0] : Index[1] : Index[2]]
|
||||
SliceExpr struct {
|
||||
X Expr
|
||||
Index [3]Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// X.(Type)
|
||||
AssertExpr struct {
|
||||
X Expr
|
||||
// TODO(gri) consider using Name{"..."} instead of nil (permits attaching of comments)
|
||||
Type Expr
|
||||
expr
|
||||
}
|
||||
|
||||
Operation struct {
|
||||
Op Operator
|
||||
X, Y Expr // Y == nil means unary expression
|
||||
expr
|
||||
}
|
||||
|
||||
// Fun(ArgList[0], ArgList[1], ...)
|
||||
CallExpr struct {
|
||||
Fun Expr
|
||||
ArgList []Expr
|
||||
HasDots bool // last argument is followed by ...
|
||||
expr
|
||||
}
|
||||
|
||||
// ElemList[0], ElemList[1], ...
|
||||
ListExpr struct {
|
||||
ElemList []Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// [Len]Elem
|
||||
ArrayType struct {
|
||||
// TODO(gri) consider using Name{"..."} instead of nil (permits attaching of comments)
|
||||
Len Expr // nil means Len is ...
|
||||
Elem Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// []Elem
|
||||
SliceType struct {
|
||||
Elem Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// ...Elem
|
||||
DotsType struct {
|
||||
Elem Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// struct { FieldList[0] TagList[0]; FieldList[1] TagList[1]; ... }
|
||||
StructType struct {
|
||||
FieldList []*Field
|
||||
TagList []*BasicLit // i >= len(TagList) || TagList[i] == nil means no tag for field i
|
||||
expr
|
||||
}
|
||||
|
||||
// Name Type
|
||||
// Type
|
||||
Field struct {
|
||||
Name *Name // nil means anonymous field/parameter (structs/parameters), or embedded interface (interfaces)
|
||||
Type Expr // field names declared in a list share the same Type (identical pointers)
|
||||
node
|
||||
}
|
||||
|
||||
// interface { MethodList[0]; MethodList[1]; ... }
|
||||
InterfaceType struct {
|
||||
MethodList []*Field
|
||||
expr
|
||||
}
|
||||
|
||||
FuncType struct {
|
||||
ParamList []*Field
|
||||
ResultList []*Field
|
||||
expr
|
||||
}
|
||||
|
||||
// map[Key]Value
|
||||
MapType struct {
|
||||
Key Expr
|
||||
Value Expr
|
||||
expr
|
||||
}
|
||||
|
||||
// chan Elem
|
||||
// <-chan Elem
|
||||
// chan<- Elem
|
||||
ChanType struct {
|
||||
Dir ChanDir // 0 means no direction
|
||||
Elem Expr
|
||||
expr
|
||||
}
|
||||
)
|
||||
|
||||
type expr struct{ node }
|
||||
|
||||
func (*expr) aExpr() {}
|
||||
|
||||
type ChanDir uint
|
||||
|
||||
const (
|
||||
_ ChanDir = iota
|
||||
SendOnly
|
||||
RecvOnly
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Statements
|
||||
|
||||
type (
|
||||
Stmt interface {
|
||||
Node
|
||||
aStmt()
|
||||
}
|
||||
|
||||
SimpleStmt interface {
|
||||
Stmt
|
||||
aSimpleStmt()
|
||||
}
|
||||
|
||||
EmptyStmt struct {
|
||||
simpleStmt
|
||||
}
|
||||
|
||||
LabeledStmt struct {
|
||||
Label *Name
|
||||
Stmt Stmt
|
||||
stmt
|
||||
}
|
||||
|
||||
BlockStmt struct {
|
||||
Body []Stmt
|
||||
stmt
|
||||
}
|
||||
|
||||
ExprStmt struct {
|
||||
X Expr
|
||||
simpleStmt
|
||||
}
|
||||
|
||||
SendStmt struct {
|
||||
Chan, Value Expr // Chan <- Value
|
||||
simpleStmt
|
||||
}
|
||||
|
||||
DeclStmt struct {
|
||||
DeclList []Decl
|
||||
stmt
|
||||
}
|
||||
|
||||
AssignStmt struct {
|
||||
Op Operator // 0 means no operation
|
||||
Lhs, Rhs Expr // Rhs == ImplicitOne means Lhs++ (Op == Add) or Lhs-- (Op == Sub)
|
||||
simpleStmt
|
||||
}
|
||||
|
||||
BranchStmt struct {
|
||||
Tok token // Break, Continue, Fallthrough, or Goto
|
||||
Label *Name
|
||||
stmt
|
||||
}
|
||||
|
||||
CallStmt struct {
|
||||
Tok token // Go or Defer
|
||||
Call *CallExpr
|
||||
stmt
|
||||
}
|
||||
|
||||
ReturnStmt struct {
|
||||
Results Expr // nil means no explicit return values
|
||||
stmt
|
||||
}
|
||||
|
||||
IfStmt struct {
|
||||
Init SimpleStmt
|
||||
Cond Expr
|
||||
Then []Stmt
|
||||
Else Stmt // either *IfStmt or *BlockStmt
|
||||
stmt
|
||||
}
|
||||
|
||||
ForStmt struct {
|
||||
Init SimpleStmt // incl. *RangeClause
|
||||
Cond Expr
|
||||
Post SimpleStmt
|
||||
Body []Stmt
|
||||
stmt
|
||||
}
|
||||
|
||||
SwitchStmt struct {
|
||||
Init SimpleStmt
|
||||
Tag Expr
|
||||
Body []*CaseClause
|
||||
stmt
|
||||
}
|
||||
|
||||
SelectStmt struct {
|
||||
Body []*CommClause
|
||||
stmt
|
||||
}
|
||||
)
|
||||
|
||||
type (
|
||||
RangeClause struct {
|
||||
Lhs Expr // nil means no Lhs = or Lhs :=
|
||||
Def bool // means :=
|
||||
X Expr // range X
|
||||
simpleStmt
|
||||
}
|
||||
|
||||
TypeSwitchGuard struct {
|
||||
// TODO(gri) consider using Name{"..."} instead of nil (permits attaching of comments)
|
||||
Lhs *Name // nil means no Lhs :=
|
||||
X Expr // X.(type)
|
||||
expr
|
||||
}
|
||||
|
||||
CaseClause struct {
|
||||
Cases Expr // nil means default clause
|
||||
Body []Stmt
|
||||
node
|
||||
}
|
||||
|
||||
CommClause struct {
|
||||
Comm SimpleStmt // send or receive stmt; nil means default clause
|
||||
Body []Stmt
|
||||
node
|
||||
}
|
||||
)
|
||||
|
||||
type stmt struct{ node }
|
||||
|
||||
func (stmt) aStmt() {}
|
||||
|
||||
type simpleStmt struct {
|
||||
stmt
|
||||
}
|
||||
|
||||
func (simpleStmt) aSimpleStmt() {}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Comments
|
||||
|
||||
type CommentKind uint
|
||||
|
||||
const (
|
||||
Above CommentKind = iota
|
||||
Below
|
||||
Left
|
||||
Right
|
||||
)
|
||||
|
||||
type Comment struct {
|
||||
Kind CommentKind
|
||||
Text string
|
||||
Next *Comment
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue