]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/parser: improved a couple of error messages
authorRobert Griesemer <gri@golang.org>
Wed, 22 Feb 2017 21:43:23 +0000 (13:43 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 24 Feb 2017 18:54:36 +0000 (18:54 +0000)
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>
src/cmd/compile/internal/syntax/parser.go
test/syntax/chan1.go
test/syntax/semi4.go

index 585765e5564875576f8b0a785059029f8a77cf45..d57e02bfe058e88688ba2a3f5437b3e9bd0dd4cc 100644 (file)
@@ -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
index a33a0d4cea2791ab5e5b09200f7636b9ea82de17..4eb63796ac52d1d293f2fc747464be5d661ee766 100644 (file)
@@ -10,8 +10,8 @@ var c chan int
 var v int
 
 func main() {
-       if c <- v { // ERROR "used as value|missing condition|invalid condition"
+       if c <- v { // ERROR "used as value"
        }
 }
 
-var _ = c <- v // ERROR "used as value|unexpected <-"
+var _ = c <- v // ERROR "unexpected <-"
index 0b5e6776805a7d37d8f54ab8a0ae91beb2db0516..f21431b3f53e62c0072269dcf09b517bf35e2724 100644 (file)
@@ -4,14 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// TODO(mdempsky): Update error expectations for new parser.
-// The new parser emits an extra "missing { after for clause" error.
-// The old parser is supposed to emit this too, but it panics first
-// due to a nil pointer dereference.
-
 package main
 
 func main() {
        for x           // GCCGO_ERROR "undefined"
-       {               // ERROR "expecting .*{.* after for clause|missing operand"
-               z       // ERROR "undefined|expecting { after for clause"
+       {               // ERROR "unexpected {, expecting for loop condition"
+               z