aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/syntax/scanner.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2017-02-16 12:52:01 -0800
committerRobert Griesemer <gri@golang.org>2017-02-16 21:46:43 +0000
commit1693e7b6f2ad1bd2a800161e92b5ac8d3d882663 (patch)
treecd481aa17fedca57de165740e78e439e98af4e17 /src/cmd/compile/internal/syntax/scanner.go
parent990124da2a6ca5a54b38733b51018e2f8758cfae (diff)
downloadgo-1693e7b6f2ad1bd2a800161e92b5ac8d3d882663.tar.gz
go-1693e7b6f2ad1bd2a800161e92b5ac8d3d882663.zip
cmd/compile/internal/syntax: better errors and recovery for invalid character literals
Fixes #15611. Change-Id: I352b145026466cafef8cf87addafbd30716bda24 Reviewed-on: https://go-review.googlesource.com/37138 Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/syntax/scanner.go')
-rw-r--r--src/cmd/compile/internal/syntax/scanner.go79
1 files changed, 47 insertions, 32 deletions
diff --git a/src/cmd/compile/internal/syntax/scanner.go b/src/cmd/compile/internal/syntax/scanner.go
index edd60609a0..c2de9ce686 100644
--- a/src/cmd/compile/internal/syntax/scanner.go
+++ b/src/cmd/compile/internal/syntax/scanner.go
@@ -466,6 +466,53 @@ done:
s.tok = _Literal
}
+func (s *scanner) rune() {
+ s.startLit()
+
+ ok := true // only report errors if we're ok so far
+ n := 0
+ for ; ; n++ {
+ r := s.getr()
+ if r == '\'' {
+ break
+ }
+ if r == '\\' {
+ if !s.escape('\'') {
+ ok = false
+ }
+ continue
+ }
+ if r == '\n' {
+ s.ungetr() // assume newline is not part of literal
+ if ok {
+ s.error("newline in character literal")
+ ok = false
+ }
+ break
+ }
+ if r < 0 {
+ if ok {
+ s.errh(s.line, s.col, "invalid character literal (missing closing ')")
+ ok = false
+ }
+ break
+ }
+ }
+
+ if ok {
+ if n == 0 {
+ s.error("empty character literal or unescaped ' in character literal")
+ } else if n != 1 {
+ s.errh(s.line, s.col, "invalid character literal (more than one character)")
+ }
+ }
+
+ s.nlsemi = true
+ s.lit = string(s.stopLit())
+ s.kind = RuneLit
+ s.tok = _Literal
+}
+
func (s *scanner) stdString() {
s.startLit()
@@ -518,38 +565,6 @@ func (s *scanner) rawString() {
s.tok = _Literal
}
-func (s *scanner) rune() {
- s.startLit()
-
- r := s.getr()
- ok := false
- if r == '\'' {
- s.error("empty character literal or unescaped ' in character literal")
- } else if r == '\n' {
- s.ungetr() // assume newline is not part of literal
- s.error("newline in character literal")
- } else {
- ok = true
- if r == '\\' {
- ok = s.escape('\'')
- }
- }
-
- r = s.getr()
- if r != '\'' {
- // only report error if we're ok so far
- if ok {
- s.error("missing '")
- }
- s.ungetr()
- }
-
- s.nlsemi = true
- s.lit = string(s.stopLit())
- s.kind = RuneLit
- s.tok = _Literal
-}
-
func (s *scanner) skipLine(r rune) {
for r >= 0 {
if r == '\n' {