[go] cmd/compile/internal/syntax: better errors for syntax errors in lists

169 views
Skip to first unread message

Robert Griesemer (Gerrit)

unread,
Mar 30, 2022, 8:27:01 PM3/30/22
to Robert Griesemer, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Ian Lance Taylor, Gopher Robot, golang-co...@googlegroups.com

Robert Griesemer submitted this change.

View Change



3 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted one.

Approvals: Ian Lance Taylor: Looks good to me, approved Robert Griesemer: Trusted
cmd/compile/internal/syntax: better errors for syntax errors in lists

For syntax errors in various (syntactic) lists, instead of reporting
a set of "expected" tokens (which may be incomplete), provide context
and mention "possibly missing" tokens. The result is a friendlier and
more accurate error message.

Fixes #49205.

Change-Id: I38ae7bf62febfe790075e62deb33ec8c17d64476
Reviewed-on: https://go-review.googlesource.com/c/go/+/396914
Trust: Robert Griesemer <g...@golang.org>
Reviewed-by: Ian Lance Taylor <ia...@golang.org>
---
M src/cmd/compile/internal/syntax/parser.go
A src/cmd/compile/internal/syntax/testdata/issue49205.go
M test/fixedbugs/issue13319.go
M test/syntax/composite.go
4 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 805bf13..39ea0cc 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -472,7 +472,7 @@
//
// list = [ f { sep f } [sep] ] close .
//
-func (p *parser) list(sep, close token, f func() bool) Pos {
+func (p *parser) list(context string, sep, close token, f func() bool) Pos {
if debug && (sep != _Comma && sep != _Semi || close != _Rparen && close != _Rbrace && close != _Rbrack) {
panic("invalid sep or close argument for list")
}
@@ -482,7 +482,7 @@
done = f()
// sep is optional before close
if !p.got(sep) && p.tok != close {
- p.syntaxError(fmt.Sprintf("expecting %s or %s", tokstring(sep), tokstring(close)))
+ p.syntaxError(fmt.Sprintf("in %s; possibly missing %s or %s", context, tokstring(sep), tokstring(close)))
p.advance(_Rparen, _Rbrack, _Rbrace)
if p.tok != close {
// position could be better but we had an error so we don't care
@@ -502,7 +502,7 @@
g := new(Group)
p.clearPragma()
p.next() // must consume "(" after calling clearPragma!
- p.list(_Semi, _Rparen, func() bool {
+ p.list("grouped declaration", _Semi, _Rparen, func() bool {
if x := f(g); x != nil {
list = append(list, x)
}
@@ -1233,7 +1233,7 @@

p.xnest++
p.want(_Lbrace)
- x.Rbrace = p.list(_Comma, _Rbrace, func() bool {
+ x.Rbrace = p.list("composite literal", _Comma, _Rbrace, func() bool {
// value
e := p.bare_complitexpr()
if p.tok == _Colon {
@@ -1477,7 +1477,7 @@

p.want(_Struct)
p.want(_Lbrace)
- p.list(_Semi, _Rbrace, func() bool {
+ p.list("struct type", _Semi, _Rbrace, func() bool {
p.fieldDecl(typ)
return false
})
@@ -1497,7 +1497,7 @@

p.want(_Interface)
p.want(_Lbrace)
- p.list(_Semi, _Rbrace, func() bool {
+ p.list("interface type", _Semi, _Rbrace, func() bool {
switch p.tok {
case _Name:
f := p.methodDecl()
@@ -1980,7 +1980,7 @@

var named int // number of parameters that have an explicit name and type
var typed int // number of parameters that have an explicit type
- end := p.list(_Comma, close, func() bool {
+ end := p.list("parameter list", _Comma, close, func() bool {
var par *Field
if typ != nil {
if debug && name == nil {
@@ -2660,7 +2660,7 @@
}

p.xnest++
- p.list(_Comma, _Rparen, func() bool {
+ p.list("argument list", _Comma, _Rparen, func() bool {
list = append(list, p.expr())
hasDots = p.got(_DotDotDot)
return hasDots
diff --git a/src/cmd/compile/internal/syntax/testdata/issue49205.go b/src/cmd/compile/internal/syntax/testdata/issue49205.go
new file mode 100644
index 0000000..bbcc950
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/issue49205.go
@@ -0,0 +1,27 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// test case from issue
+
+type _ interface{
+ m /* ERROR unexpected int in interface type; possibly missing semicolon or newline or } */ int
+}
+
+// other cases where the fix for this issue affects the error message
+
+const (
+ x int = 10 /* ERROR unexpected literal "foo" in grouped declaration; possibly missing semicolon or newline or \) */ "foo"
+)
+
+var _ = []int{1, 2, 3 /* ERROR unexpected int in composite literal; possibly missing comma or } */ int }
+
+type _ struct {
+ x y /* ERROR syntax error: unexpected comma in struct type; possibly missing semicolon or newline or } */ ,
+}
+
+func f(a, b c /* ERROR unexpected d in parameter list; possibly missing comma or \) */ d) {
+ f(a, b, c /* ERROR unexpected d in argument list; possibly missing comma or \) */ d)
+}
diff --git a/test/fixedbugs/issue13319.go b/test/fixedbugs/issue13319.go
index c9b4896..7e1df3e 100644
--- a/test/fixedbugs/issue13319.go
+++ b/test/fixedbugs/issue13319.go
@@ -9,10 +9,10 @@
func f(int, int) {
switch x {
case 1:
- f(1, g() // ERROR "expecting \)|expecting comma or \)"
+ f(1, g() // ERROR "expecting \)|possibly missing comma or \)"
case 2:
f()
case 3:
- f(1, g() // ERROR "expecting \)|expecting comma or \)"
+ f(1, g() // ERROR "expecting \)|possibly missing comma or \)"
}
}
diff --git a/test/syntax/composite.go b/test/syntax/composite.go
index f891931..b4e03f3 100644
--- a/test/syntax/composite.go
+++ b/test/syntax/composite.go
@@ -7,5 +7,5 @@
package main

var a = []int{
- 3 // ERROR "need trailing comma before newline in composite literal|expecting comma or }"
+ 3 // ERROR "need trailing comma before newline in composite literal|possibly missing comma or }"
}

To view, visit change 396914. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I38ae7bf62febfe790075e62deb33ec8c17d64476
Gerrit-Change-Number: 396914
Gerrit-PatchSet: 6
Gerrit-Owner: Robert Griesemer <g...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages