github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/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 // The base argument is only used for position information. 45 // 46 // If errh != nil, it is called with each error encountered, and Parse will 47 // process as much source as possible. If errh is nil, Parse will terminate 48 // immediately upon encountering an error. 49 // 50 // If a PragmaHandler is provided, it is called with each pragma encountered. 51 // 52 // The Mode argument is currently ignored. 53 func Parse(base *src.PosBase, src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, first error) { 54 defer func() { 55 if p := recover(); p != nil { 56 if err, ok := p.(Error); ok { 57 first = err 58 return 59 } 60 panic(p) 61 } 62 }() 63 64 var p parser 65 p.init(base, src, errh, pragh) 66 p.next() 67 return p.file(), p.first 68 } 69 70 // ParseBytes behaves like Parse but it reads the source from the []byte slice provided. 71 func ParseBytes(base *src.PosBase, src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) { 72 return Parse(base, &bytesReader{src}, errh, pragh, mode) 73 } 74 75 type bytesReader struct { 76 data []byte 77 } 78 79 func (r *bytesReader) Read(p []byte) (int, error) { 80 if len(r.data) > 0 { 81 n := copy(p, r.data) 82 r.data = r.data[n:] 83 return n, nil 84 } 85 return 0, io.EOF 86 } 87 88 // ParseFile behaves like Parse but it reads the source from the named file. 89 func ParseFile(filename string, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) { 90 f, err := os.Open(filename) 91 if err != nil { 92 if errh != nil { 93 errh(err) 94 } 95 return nil, err 96 } 97 defer f.Close() 98 return Parse(src.NewFileBase(filename, filename), f, errh, pragh, mode) 99 }