aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2016-06-10 14:34:00 -0700
committerMatthew Dempsky <mdempsky@google.com>2016-08-16 14:32:08 -0700
commitf82bd3cc7d49491d43846907e4a1e63f1e42cef9 (patch)
treee4140c739ca0056223e3c11e16524b13ad0df305
parent3c72ed3bfaa29c26333acbf83476dca9e97a1f36 (diff)
downloadgo-f82bd3cc7d49491d43846907e4a1e63f1e42cef9.tar.gz
go-f82bd3cc7d49491d43846907e4a1e63f1e42cef9.zip
cmd/compile/internal/syntax: better error positions for scanner errors
For string/comment not terminated errors, report error at the start of the string/comment rather than the end of the file.
-rw-r--r--src/cmd/compile/internal/syntax/scanner.go8
-rw-r--r--src/cmd/compile/internal/syntax/scanner_test.go29
-rw-r--r--src/cmd/compile/internal/syntax/source.go5
3 files changed, 22 insertions, 20 deletions
diff --git a/src/cmd/compile/internal/syntax/scanner.go b/src/cmd/compile/internal/syntax/scanner.go
index f146c8cb6f..dcbe49e82a 100644
--- a/src/cmd/compile/internal/syntax/scanner.go
+++ b/src/cmd/compile/internal/syntax/scanner.go
@@ -44,7 +44,7 @@ redo:
}
// token start
- s.pos, s.line = s.source.pos(), s.source.line
+ s.pos, s.line = s.source.pos0(), s.source.line0
if isLetter(c) || c >= utf8.RuneSelf && unicode.IsLetter(c) {
s.ident()
@@ -461,7 +461,7 @@ func (s *scanner) stdString() {
break
}
if r < 0 {
- s.error("string not terminated") // TODO(gri) should point at start of string
+ s.error_at(s.pos, s.line, "string not terminated")
break
}
}
@@ -481,7 +481,7 @@ func (s *scanner) rawString() {
break
}
if r < 0 {
- s.error("string not terminated") // TODO(gri) should point at start of string
+ s.error_at(s.pos, s.line, "string not terminated")
break
}
}
@@ -578,7 +578,7 @@ func (s *scanner) fullComment() {
}
}
if r < 0 {
- s.error("comment not terminated")
+ s.error_at(s.pos, s.line, "comment not terminated")
return
}
}
diff --git a/src/cmd/compile/internal/syntax/scanner_test.go b/src/cmd/compile/internal/syntax/scanner_test.go
index dca838dafa..69e81aceca 100644
--- a/src/cmd/compile/internal/syntax/scanner_test.go
+++ b/src/cmd/compile/internal/syntax/scanner_test.go
@@ -272,8 +272,8 @@ func TestScanErrors(t *testing.T) {
{"foo$bar = 0", "invalid rune '$'", 3, 1},
{"const x = 0xyz", "malformed hex constant", 12, 1},
{"0123456789", "malformed octal constant", 10, 1},
- {"0123456789. /*", "comment not terminated", 14, 1}, // valid float constant
- {"0123456789e0 /*", "comment not terminated", 15, 1}, // valid float constant
+ {"0123456789. /* foobar", "comment not terminated", 12, 1}, // valid float constant
+ {"0123456789e0 /*\nfoobar", "comment not terminated", 13, 1}, // valid float constant
{"var a, b = 08, 07\n", "malformed octal constant", 13, 1},
{"(x + 1.0e+x)", "malformed floating-point constant exponent", 10, 1},
@@ -286,32 +286,33 @@ func TestScanErrors(t *testing.T) {
{`'\y'`, "unknown escape sequence", 2, 1},
{`'\x0'`, "escape sequence incomplete", 4, 1},
{`'\00'`, "escape sequence incomplete", 4, 1},
- {`'\377' /*`, "comment not terminated", 9, 1}, // valid octal escape
+ {`'\377' /*`, "comment not terminated", 7, 1}, // valid octal escape
{`'\378`, "illegal character U+0038 '8' in escape sequence", 4, 1},
{`'\400'`, "octal escape value > 255: 256", 5, 1},
{`'xx`, "missing '", 2, 1},
{"\"\n", "newline in string", 1, 1},
- {`"`, "string not terminated", 1, 1},
- {`"foo`, "string not terminated", 4, 1},
- {"`", "string not terminated", 1, 1},
- {"`foo", "string not terminated", 4, 1},
- {"/*/", "comment not terminated", 3, 1},
- {"/*\n\nfoo", "comment not terminated", 7, 3},
- {`"\`, "string not terminated", 2, 1},
- {`"\"`, "string not terminated", 3, 1},
- {`"\x`, "string not terminated", 3, 1},
+ {`"`, "string not terminated", 0, 1},
+ {`"foo`, "string not terminated", 0, 1},
+ {"`", "string not terminated", 0, 1},
+ {"`foo", "string not terminated", 0, 1},
+ {"/*/", "comment not terminated", 0, 1},
+ {"/*\n\nfoo", "comment not terminated", 0, 1},
+ {"/*\n\nfoo", "comment not terminated", 0, 1},
+ {`"\`, "string not terminated", 0, 1},
+ {`"\"`, "string not terminated", 0, 1},
+ {`"\x`, "string not terminated", 0, 1},
{`"\x"`, "escape sequence incomplete", 3, 1},
{`"\y"`, "unknown escape sequence", 2, 1},
{`"\x0"`, "escape sequence incomplete", 4, 1},
{`"\00"`, "escape sequence incomplete", 4, 1},
- {`"\377" /*`, "comment not terminated", 9, 1}, // valid octal escape
+ {`"\377" /*`, "comment not terminated", 7, 1}, // valid octal escape
{`"\378"`, "illegal character U+0038 '8' in escape sequence", 4, 1},
{`"\400"`, "octal escape value > 255: 256", 5, 1},
{`s := "foo\z"`, "unknown escape sequence", 10, 1},
{`s := "foo\z00\nbar"`, "unknown escape sequence", 10, 1},
- {`"\x`, "string not terminated", 3, 1},
+ {`"\x`, "string not terminated", 0, 1},
{`"\x"`, "escape sequence incomplete", 3, 1},
{`var s string = "\x"`, "escape sequence incomplete", 18, 1},
{`return "\Uffffffff"`, "escape sequence is invalid Unicode code point", 18, 1},
diff --git a/src/cmd/compile/internal/syntax/source.go b/src/cmd/compile/internal/syntax/source.go
index 577d7cb168..87c22fcc26 100644
--- a/src/cmd/compile/internal/syntax/source.go
+++ b/src/cmd/compile/internal/syntax/source.go
@@ -46,7 +46,7 @@ func (s *source) init(src io.Reader, errh ErrorHandler) {
}
func (s *source) error(msg string) {
- s.error_at(s.pos(), s.line, msg)
+ s.error_at(s.pos0(), s.line0, msg)
}
func (s *source) error_at(pos, line int, msg string) {
@@ -57,7 +57,8 @@ func (s *source) error_at(pos, line int, msg string) {
panic(fmt.Sprintf("%d: %s", line, msg))
}
-func (s *source) pos() int {
+// pos0 returns the byte position of the last character read.
+func (s *source) pos0() int {
return s.offs + s.r0
}