aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/syntax/syntax.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/syntax/syntax.go')
-rw-r--r--src/cmd/compile/internal/syntax/syntax.go99
1 files changed, 57 insertions, 42 deletions
diff --git a/src/cmd/compile/internal/syntax/syntax.go b/src/cmd/compile/internal/syntax/syntax.go
index 71fc097c3b..b1e56ee946 100644
--- a/src/cmd/compile/internal/syntax/syntax.go
+++ b/src/cmd/compile/internal/syntax/syntax.go
@@ -5,35 +5,72 @@
package syntax
import (
- "errors"
"fmt"
"io"
"os"
)
+// Mode describes the parser mode.
type Mode uint
+// Error describes a syntax error. Error implements the error interface.
+type Error struct {
+ // TODO(gri) decide what we really need here
+ Pos int // byte offset from file start
+ Line int // line (starting with 1)
+ Msg string
+}
+
+func (err Error) Error() string {
+ return fmt.Sprintf("%d: %s", err.Line, err.Msg)
+}
+
+var _ error = Error{} // verify that Error implements error
+
+// An ErrorHandler is called for each error encountered reading a .go file.
+type ErrorHandler func(err error)
+
// A Pragma value is a set of flags that augment a function or
// type declaration. Callers may assign meaning to the flags as
// appropriate.
type Pragma uint16
-type ErrorHandler func(pos, line int, msg string)
-
// A PragmaHandler is used to process //line and //go: directives as
// they're scanned. The returned Pragma value will be unioned into the
// next FuncDecl node.
type PragmaHandler func(pos, line int, text string) Pragma
-// TODO(gri) These need a lot more work.
+// Parse parses a single Go source file from src and returns the corresponding
+// syntax tree. If there are syntax errors, Parse will return the first error
+// encountered.
+//
+// If errh != nil, it is called with each error encountered, and Parse will
+// process as much source as possible. If errh is nil, Parse will terminate
+// immediately upon encountering an error.
+//
+// If a PragmaHandler is provided, it is called with each pragma encountered.
+//
+// The Mode argument is currently ignored.
+func Parse(src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ var ok bool
+ if err, ok = p.(Error); ok {
+ return
+ }
+ panic(p)
+ }
+ }()
-func ReadFile(filename string, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) {
- src, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer src.Close()
- return Read(src, errh, pragh, mode)
+ var p parser
+ p.init(src, errh, pragh)
+ p.next()
+ return p.file(), p.first
+}
+
+// ParseBytes behaves like Parse but it reads the source from the []byte slice provided.
+func ParseBytes(src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) {
+ return Parse(&bytesReader{src}, errh, pragh, mode)
}
type bytesReader struct {
@@ -49,37 +86,15 @@ func (r *bytesReader) Read(p []byte) (int, error) {
return 0, io.EOF
}
-func ReadBytes(src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) {
- return Read(&bytesReader{src}, errh, pragh, mode)
-}
-
-func Read(src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (ast *File, err error) {
- defer func() {
- if p := recover(); p != nil {
- if msg, ok := p.(parserError); ok {
- err = errors.New(string(msg))
- return
- }
- panic(p)
+// ParseFile behaves like Parse but it reads the source from the named file.
+func ParseFile(filename string, errh ErrorHandler, pragh PragmaHandler, mode Mode) (*File, error) {
+ src, err := os.Open(filename)
+ if err != nil {
+ if errh != nil {
+ errh(err)
}
- }()
-
- var p parser
- p.init(src, errh, pragh)
- p.next()
- ast = p.file()
-
- // TODO(gri) This isn't quite right: Even if there's an error handler installed
- // we should report an error if parsing found syntax errors. This also
- // requires updating the noder's ReadFile call.
- if errh == nil && p.nerrors > 0 {
- ast = nil
- err = fmt.Errorf("%d syntax errors", p.nerrors)
+ return nil, err
}
-
- return
-}
-
-func Write(w io.Writer, n *File) error {
- panic("unimplemented")
+ defer src.Close()
+ return Parse(src, errh, pragh, mode)
}