github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/cmd/compile/internal/syntax/syntax.go (about) 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 "cmd/internal/src" 9 "fmt" 10 "io" 11 "os" 12 ) 13 14 // Mode describes the parser mode. 15 type Mode uint 16 17 // Error describes a syntax error. Error implements the error interface. 18 type Error struct { 19 Pos src.Pos 20 Msg string 21 } 22 23 func (err Error) Error() string { 24 return fmt.Sprintf("%s: %s", err.Pos, err.Msg) 25 } 26 27 var _ error = Error{} // verify that Error implements error 28 29 // An ErrorHandler is called for each error encountered reading a .go file. 30 type ErrorHandler func(err error) 31 32 // A Pragma value is a set of flags that augment a function or 33 // type declaration. Callers may assign meaning to the flags as 34 // appropriate. 35 type Pragma uint16 36 37 // A PragmaHandler is used to process //line and //go: directives as 38 // they're scanned. The returned Pragma value will be unioned into the 39 // next FuncDecl node. 40 type PragmaHandler func(pos src.Pos, text string) Pragma 41 42 // Parse parses a single Go source file from src and returns the corresponding 43 // syntax tree. If there are errors, Parse will return the first error found, 44 // and a possibly partially constructed syntax tree, or nil if no correct package 45 // clause was found. The base argument is only used for position information. 46 // 47 // If errh != nil, it is called with each error encountered, and Parse will 48 // process as much source as possible. If errh is nil, Parse will terminate 49 // immediately upon encountering an error. 50 // 51 // If a PragmaHandler is provided, it is called with each pragma encountered. 52 // 53 // The Mode argument is currently ignored. 54 func Parse(base *src.PosBase, src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, first error) { 55 defer func() { 56 if p := recover(); p != nil { 57 if err, ok := p.(Error); ok { 58 first = err 59 return 60 } 61 panic(p) 62 } 63 }() 64 65 var p parser 66 p.init(base, src, errh, pragh) 67 p.next() 68 return p.fileOrNil(), p.first 69 } 70 71 // ParseBytes behaves like Parse but it reads the source from the []byte slice provided. 72 func ParseBytes(base *src.PosBase, src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) { 73 return Parse(base, &bytesReader{src}, errh, pragh, mode) 74 } 75 76 type bytesReader struct { 77 data []byte 78 } 79 80 func (r *bytesReader) Read(p []byte) (int, error) { 81 if len(r.data) > 0 { 82 n := copy(p, r.data) 83 r.data = r.data[n:] 84 return n, nil 85 } 86 return 0, io.EOF 87 } 88 89 // ParseFile behaves like Parse but it reads the source from the named file. 90 func ParseFile(filename string, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) { 91 f, err := os.Open(filename) 92 if err != nil { 93 if errh != nil { 94 errh(err) 95 } 96 return nil, err 97 } 98 defer f.Close() 99 return Parse(src.NewFileBase(filename, filename), f, errh, pragh, mode) 100 }