diff options
| author | Robert Griesemer <gri@golang.org> | 2017-02-22 13:43:23 -0800 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2017-02-24 18:54:36 +0000 |
| commit | f8ae30c4a201dbdb6652cbb72cd51762863c7447 (patch) | |
| tree | 9fcddc62fe6d6b5fb9b2c688c9d57569b693fa7c /src | |
| parent | 2fa09a20e56eb27f7cec635be42fc3137c091085 (diff) | |
| download | go-f8ae30c4a201dbdb6652cbb72cd51762863c7447.tar.xz | |
cmd/compile/internal/parser: improved a couple of error messages
The new syntax tree introduced with 1.8 represents send statements
(ch <- x) as statements; the old syntax tree represented them as
expressions (and parsed them as such) but complained if they were
used in expression context. As a consequence, some of the errors
that in the past were of the form "ch <- x used as value" now look
like "unexpected <- ..." because a "<-" is not valid according to
Go syntax in those situations. Accept the new error message.
Also: Fine-tune handling of misformed for loop headers.
Also: Minor cleanups/better comments.
Fixes #17590.
Change-Id: Ia541dea1f2f015c1b21f5b3ae44aacdec60a8aba
Reviewed-on: https://go-review.googlesource.com/37386
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/syntax/parser.go | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go index 585765e556..d57e02bfe0 100644 --- a/src/cmd/compile/internal/syntax/parser.go +++ b/src/cmd/compile/internal/syntax/parser.go @@ -663,7 +663,7 @@ func (p *parser) operand(keep_parens bool) Expr { pos := p.pos() p.next() p.xnest++ - x := p.expr() // expr_or_type + x := p.expr() p.xnest-- p.want(_Rparen) @@ -719,12 +719,6 @@ func (p *parser) operand(keep_parens bool) Expr { case _Lbrack, _Chan, _Map, _Struct, _Interface: return p.type_() // othertype - case _Lbrace: - // common case: p.header is missing simpleStmt before { in if, for, switch - p.syntax_error("missing operand") - // '{' will be consumed in pexpr - no need to consume it here - return nil - default: p.syntax_error("expecting expression") p.advance() @@ -850,12 +844,12 @@ loop: // operand may have returned a parenthesized complit // type; accept it but complain if we have a complit t := unparen(x) - // determine if '{' belongs to a complit or a compound_stmt + // determine if '{' belongs to a composite literal or a block statement complit_ok := false switch t.(type) { case *Name, *SelectorExpr: if p.xnest >= 0 { - // x is considered a comptype + // x is considered a composite literal type complit_ok = true } case *ArrayType, *SliceType, *StructType, *MapType: @@ -1692,6 +1686,7 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS } return } + // p.tok != _Lbrace outer := p.xnest p.xnest = -1 @@ -1712,7 +1707,7 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS var condStmt SimpleStmt var semi struct { pos src.Pos - lit string + lit string // valid if pos.IsKnown() } if p.tok == _Semi { semi.pos = p.pos() @@ -1720,6 +1715,10 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS p.next() if keyword == _For { if p.tok != _Semi { + if p.tok == _Lbrace { + p.syntax_error("expecting for loop condition") + goto done + } condStmt = p.simpleStmt(nil, false) } p.want(_Semi) @@ -1734,10 +1733,11 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS init = nil } +done: // unpack condStmt switch s := condStmt.(type) { case nil: - if keyword == _If { + if keyword == _If && semi.pos.IsKnown() { if semi.lit != "semicolon" { p.syntax_error_at(semi.pos, fmt.Sprintf("unexpected %s, expecting { after if clause", semi.lit)) } else { @@ -2037,7 +2037,7 @@ func (p *parser) call(fun Expr) *CallExpr { p.xnest++ for p.tok != _EOF && p.tok != _Rparen { - c.ArgList = append(c.ArgList, p.expr()) // expr_or_type + c.ArgList = append(c.ArgList, p.expr()) c.HasDots = p.got(_DotDotDot) if !p.ocomma(_Rparen) || c.HasDots { break |
