Source file src/cmd/compile/internal/syntax/syntax.go
1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package syntax 6 7 import ( 8 "fmt" 9 "io" 10 "os" 11 ) 12 13 // Mode describes the parser mode. 14 type Mode uint 15 16 // Modes supported by the parser. 17 const ( 18 CheckBranches Mode = 1 << iota // check correct use of labels, break, continue, and goto statements 19 AllowGenerics 20 AllowMethodTypeParams // does not support interface methods yet; ignored if AllowGenerics is not set 21 ) 22 23 // Error describes a syntax error. Error implements the error interface. 24 type Error struct { 25 Pos Pos 26 Msg string 27 } 28 29 func (err Error) Error() string { 30 return fmt.Sprintf("%s: %s", err.Pos, err.Msg) 31 } 32 33 var _ error = Error{} // verify that Error implements error 34 35 // An ErrorHandler is called for each error encountered reading a .go file. 36 type ErrorHandler func(err error) 37 38 // A Pragma value augments a package, import, const, func, type, or var declaration. 39 // Its meaning is entirely up to the PragmaHandler, 40 // except that nil is used to mean “no pragma seen.” 41 type Pragma interface{} 42 43 // A PragmaHandler is used to process //go: directives while scanning. 44 // It is passed the current pragma value, which starts out being nil, 45 // and it returns an updated pragma value. 46 // The text is the directive, with the "//" prefix stripped. 47 // The current pragma is saved at each package, import, const, func, type, or var 48 // declaration, into the File, ImportDecl, ConstDecl, FuncDecl, TypeDecl, or VarDecl node. 49 // 50 // If text is the empty string, the pragma is being returned 51 // to the handler unused, meaning it appeared before a non-declaration. 52 // The handler may wish to report an error. In this case, pos is the 53 // current parser position, not the position of the pragma itself. 54 // Blank specifies whether the line is blank before the pragma. 55 type PragmaHandler func(pos Pos, blank bool, text string, current Pragma) Pragma 56 57 // Parse parses a single Go source file from src and returns the corresponding 58 // syntax tree. If there are errors, Parse will return the first error found, 59 // and a possibly partially constructed syntax tree, or nil. 60 // 61 // If errh != nil, it is called with each error encountered, and Parse will 62 // process as much source as possible. In this case, the returned syntax tree 63 // is only nil if no correct package clause was found. 64 // If errh is nil, Parse will terminate immediately upon encountering the first 65 // error, and the returned syntax tree is nil. 66 // 67 // If pragh != nil, it is called with each pragma encountered. 68 // 69 func Parse(base *PosBase, src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, first error) { 70 defer func() { 71 if p := recover(); p != nil { 72 if err, ok := p.(Error); ok { 73 first = err 74 return 75 } 76 panic(p) 77 } 78 }() 79 80 var p parser 81 p.init(base, src, errh, pragh, mode) 82 p.next() 83 return p.fileOrNil(), p.first 84 } 85 86 // ParseFile behaves like Parse but it reads the source from the named file. 87 func ParseFile(filename string, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) { 88 f, err := os.Open(filename) 89 if err != nil { 90 if errh != nil { 91 errh(err) 92 } 93 return nil, err 94 } 95 defer f.Close() 96 return Parse(NewFileBase(filename), f, errh, pragh, mode) 97 } 98