cmd/compile/internal/syntax: fix error handling for Read/Parse calls

- define syntax.Error for cleaner error reporting
- abort parsing after first error if no error handler is installed
- make sure to always report the first error, if any
- document behavior of API calls
- while at it: rename ReadXXX -> ParseXXX (clearer)
- adjust cmd/compile noder.go accordingly

Fixes #17774.

Change-Id: I7893eedea454a64acd753e32f7a8bf811ddbb03c
Reviewed-on: https://go-review.googlesource.com/32950
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Robert Griesemer 2016-11-08 16:01:56 -08:00
parent ad020477f4
commit 60a9bf9f95
8 changed files with 126 additions and 85 deletions

View file

@ -24,27 +24,16 @@ type parser struct {
fnest int // function nesting level (for error handling)
xnest int // expression nesting level (for complit ambiguity resolution)
indent []byte // tracing support
nerrors int // error count
}
type parserError string // for error recovery if no error handler was installed
func (p *parser) init(src io.Reader, errh ErrorHandler, pragh PragmaHandler) {
p.scanner.init(src, func(pos, line int, msg string) {
p.nerrors++
if !debug && errh != nil {
errh(pos, line, msg)
return
}
panic(parserError(fmt.Sprintf("%d: %s\n", line, msg)))
}, pragh)
p.scanner.init(src, errh, pragh)
p.fnest = 0
p.xnest = 0
p.indent = nil
p.nerrors = 0
}
func (p *parser) got(tok token) bool {
@ -76,7 +65,7 @@ func (p *parser) syntax_error_at(pos, line int, msg string) {
defer p.trace("syntax_error (" + msg + ")")()
}
if p.tok == _EOF && p.nerrors > 0 {
if p.tok == _EOF && p.first != nil {
return // avoid meaningless follow-up errors
}
@ -207,7 +196,7 @@ func (p *parser) file() *File {
p.want(_Semi)
// don't bother continuing if package clause has errors
if p.nerrors > 0 {
if p.first != nil {
return nil
}