github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/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 "fmt" 9 "io" 10 "os" 11 ) 12 13 // Mode describes the parser mode. 14 type Mode uint 15 16 // Error describes a syntax error. Error implements the error interface. 17 type Error struct { 18 // TODO(gri) decide what we really need here 19 Pos int // byte offset from file start 20 Line int // line (starting with 1) 21 Msg string 22 } 23 24 func (err Error) Error() string { 25 return fmt.Sprintf("%d: %s", err.Line, err.Msg) 26 } 27 28 var _ error = Error{} // verify that Error implements error 29 30 // An ErrorHandler is called for each error encountered reading a .go file. 31 type ErrorHandler func(err error) 32 33 // A Pragma value is a set of flags that augment a function or 34 // type declaration. Callers may assign meaning to the flags as 35 // appropriate. 36 type Pragma uint16 37 38 // A PragmaHandler is used to process //line and //go: directives as 39 // they're scanned. The returned Pragma value will be unioned into the 40 // next FuncDecl node. 41 type PragmaHandler func(pos, line int, text string) Pragma 42 43 // Parse parses a single Go source file from src and returns the corresponding 44 // syntax tree. If there are syntax errors, Parse will return the first error 45 // encountered. 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(src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, err error) { 55 defer func() { 56 if p := recover(); p != nil { 57 var ok bool 58 if err, ok = p.(Error); ok { 59 return 60 } 61 panic(p) 62 } 63 }() 64 65 var p parser 66 p.init(src, errh, pragh) 67 p.next() 68 return p.file(), p.first 69 } 70 71 // ParseBytes behaves like Parse but it reads the source from the []byte slice provided. 72 func ParseBytes(src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) { 73 return Parse(&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 src, err := os.Open(filename) 92 if err != nil { 93 if errh != nil { 94 errh(err) 95 } 96 return nil, err 97 } 98 defer src.Close() 99 return Parse(src, errh, pragh, mode) 100 }