From 9ec762791eb65b92b550c3b7a8e6b9015bbf278d Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 10 Jul 2008 13:45:02 -0700 Subject: [PATCH] - filed a bug against 6g (bug065.go) - improved scanner.go error handling SVN=126706 --- test/bugs/bug065.go | 17 +++++++ test/golden.out | 34 +++++++------- usr/gri/src/scanner.go | 103 ++++++++++++++++++++++++++++------------- 3 files changed, 105 insertions(+), 49 deletions(-) create mode 100644 test/bugs/bug065.go diff --git a/test/bugs/bug065.go b/test/bugs/bug065.go new file mode 100644 index 0000000000..d7d5f74a88 --- /dev/null +++ b/test/bugs/bug065.go @@ -0,0 +1,17 @@ +// $G $D/$F.go && $L $F.$A && ./$A.out + +// Copyright 2009 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 main + +const c = '\''; // this works +const s = "\'"; // this doesn't + +/* +There is no reason why the escapes need to be different inside strings and chars. + +uetli:~/go/test/bugs gri$ 6g bug065.go +bug065.go:6: unknown escape sequence: ' +*/ diff --git a/test/golden.out b/test/golden.out index 33a60da35d..1e6283efca 100644 --- a/test/golden.out +++ b/test/golden.out @@ -33,7 +33,7 @@ hello, world =========== ./readfile.go =========== ./sieve.go -sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(201) +sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(212) BUG: known to fail incorrectly =========== ./simassign.go @@ -49,8 +49,6 @@ BUG: known to fail incorrectly =========== ./turing.go Hello World! -=========== ./utf.go - =========== ken/for.go =========== ken/interfun.go @@ -180,8 +178,8 @@ Faulting address: 0x1 pc: 0x1349 0x1349?zi - main·main(1, 0, 1606416464, ...) - main·main(0x1, 0x7fff5fbff850, 0x1, ...) + main·main(1, 0, 1606416456, ...) + main·main(0x1, 0x7fff5fbff848, 0x1, ...) BUG: incorrect code for division @@ -191,16 +189,16 @@ BUG: len should not be a keyword =========== bugs/bug054.go xxx -. CALL u(100) l(218) I{} -. . NAME-Vector_At G0 a(1) l(205) 111({},{}){} -. . AS u(1) l(218) -. . . INDREG a(1) l(218) v G0 *{} -. . . DOTPTR u(1) l(218) *{} -. . . . NAME-s G264 a(1) g(264) l(214) *{} -. . . . NAME-fields G0 a(1) l(211) -. . AS u(1) l(218) -. . . INDREG a(1) l(218) i G265 INT32 -. . . NAME-i G265 a(1) g(265) l(214) INT32 +. CALL u(100) l(229) I{} +. . NAME-Vector_At G0 a(1) l(216) 111({},{}){} +. . AS u(1) l(229) +. . . INDREG a(1) l(229) v G0 *{} +. . . DOTPTR u(1) l(229) *{} +. . . . NAME-s G279 a(1) g(279) l(225) *{} +. . . . NAME-fields G0 a(1) l(222) +. . AS u(1) l(229) +. . . INDREG a(1) l(229) i G280 INT32 +. . . NAME-i G280 a(1) g(280) l(225) INT32 bugs/bug054.go:25: fatal error: agen_inter i2s BUG: known to fail incorrectly @@ -235,6 +233,10 @@ bugs/bug064.go:15: illegal types for operand: CALL ({INT32;INT32;}) BUG: compilation should succeed +=========== bugs/bug065.go +bugs/bug065.go:6: unknown escape sequence: ' +BUG: compilation should succeed + =========== fixedbugs/bug000.go =========== fixedbugs/bug001.go @@ -293,7 +295,7 @@ fixedbugs/bug035.go:7: var f redeclared in this block =========== fixedbugs/bug037.go fixedbugs/bug037.go:6: vlong: undefined -fixedbugs/bug037.go:6: fatal error: addvar: n=NAME-s G0 a(1) l(199) t= nil +fixedbugs/bug037.go:6: fatal error: addvar: n=NAME-s G0 a(1) l(210) t= nil =========== fixedbugs/bug038.go diff --git a/usr/gri/src/scanner.go b/usr/gri/src/scanner.go index 37778033e4..7389cdac3f 100644 --- a/usr/gri/src/scanner.go +++ b/usr/gri/src/scanner.go @@ -250,26 +250,12 @@ func digit_val (ch int) int { export Scanner type Scanner struct { src string; - pos int; + pos int; // current reading position ch int; // one char look-ahead + chpos int; // position of ch } -/* -export Token -type Token struct { - val int; - beg, end int; - txt string; -} - - -func (T *Token) Print () { - print TokenName(T.val), " [", T.beg, ", ", T.end, "[ ", T.txt, "\n"; -} -*/ - - // Read the next Unicode char into S.ch. // S.ch < 0 means end-of-file. // @@ -306,12 +292,14 @@ func (S *Scanner) Next () { // 0000-007F => T1 if pos >= lim { S.ch = -1; // end of file + S.chpos = lim; return; } c0 := int(src[pos]); pos++; if c0 < Tx { S.ch = c0; + S.chpos = S.pos; S.pos = pos; return; } @@ -335,6 +323,7 @@ func (S *Scanner) Next () { goto bad; } S.ch = r; + S.chpos = S.pos; S.pos = pos; return; } @@ -355,6 +344,7 @@ func (S *Scanner) Next () { goto bad; } S.ch = r; + S.chpos = S.pos; S.pos = pos; return; } @@ -362,6 +352,7 @@ func (S *Scanner) Next () { // bad encoding bad: S.ch = Bad; + S.chpos = S.pos; S.pos += 1; return; } @@ -415,9 +406,59 @@ func (S *Scanner) Open (src string) { } +// TODO this needs to go elsewhere +func IntString(x, base int) string { + neg := false; + if x < 0 { + x = -x; + if x < 0 { + panic "smallest int not handled"; + } + neg = true; + } + + hex := "0123456789ABCDEF"; + var buf [16] byte; + i := 0; + for x > 0 || i == 0 { + buf[i] = hex[x % base]; + x /= base; + i++; + } + + s := ""; + if neg { + s = "-"; + } + for i > 0 { + i--; + s = s + string(int(buf[i])); + } + return s; +} + + + +func CharString(ch int) string { + s := string(ch); + switch ch { + case '\a': s = "\\a"; + case '\b': s = "\\b"; + case '\f': s = "\\f"; + case '\n': s = "\\n"; + case '\r': s = "\\r"; + case '\t': s = "\\t"; + case '\v': s = "\\v"; + case '\\': s = "\\"; + case '\'': s = "\\'"; + } + return "'" + s + "' (U+" + IntString(ch, 16) + ")"; +} + + func (S *Scanner) Expect (ch int) { if S.ch != ch { - S.Error(S.pos, "expected " + string(ch) + ", found " + string(S.ch)); + S.Error(S.chpos, "expected " + CharString(ch) + ", found " + CharString(S.ch)); } S.Next(); // make always progress } @@ -431,6 +472,7 @@ func (S *Scanner) SkipWhitespace () { func (S *Scanner) SkipComment () { + // '/' already consumed if S.ch == '/' { // comment S.Next(); @@ -440,8 +482,8 @@ func (S *Scanner) SkipComment () { } else { /* comment */ - pos := S.pos; - S.Next(); + pos := S.chpos - 1; + S.Expect('*'); for S.ch >= 0 { ch := S.ch; S.Next(); @@ -534,7 +576,7 @@ func (S *Scanner) ScanDigits(n int, base int) { n--; } if n > 0 { - S.Error(S.pos, "illegal char escape"); + S.Error(S.chpos, "illegal char escape"); } } @@ -543,6 +585,7 @@ func (S *Scanner) ScanEscape () string { // TODO: fix this routine ch := S.ch; + pos := S.chpos; S.Next(); switch (ch) { case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"': @@ -565,7 +608,7 @@ func (S *Scanner) ScanEscape () string { return ""; // TODO fix this default: - S.Error(S.pos, "illegal char escape"); + S.Error(pos, "illegal char escape"); } } @@ -587,12 +630,13 @@ func (S *Scanner) ScanChar () int { func (S *Scanner) ScanString () int { // '"' already consumed - pos := S.pos - 1; // TODO maybe incorrect (Unicode) + pos := S.chpos - 1; for S.ch != '"' { ch := S.ch; S.Next(); if ch == '\n' || ch < 0 { S.Error(pos, "string not terminated"); + break; } if ch == '\\' { S.ScanEscape(); @@ -607,12 +651,13 @@ func (S *Scanner) ScanString () int { func (S *Scanner) ScanRawString () int { // '`' already consumed - pos := S.pos - 1; // TODO maybe incorrect (Unicode) + pos := S.chpos - 1; for S.ch != '`' { ch := S.ch; S.Next(); if ch == '\n' || ch < 0 { S.Error(pos, "string not terminated"); + break; } } @@ -672,7 +717,7 @@ func (S *Scanner) Scan () (tok, beg, end int) { case is_letter(ch): tok = S.ScanIdentifier(); case digit_val(ch) < 10: tok = S.ScanNumber(false); default: - S.Next(); + S.Next(); // always make progress switch ch { case -1: tok = EOF; case '"': tok = S.ScanString(); @@ -712,18 +757,10 @@ func (S *Scanner) Scan () (tok, beg, end int) { case '!': tok = S.Select2(NOT, NEQ); case '&': tok = S.Select3(AND, AND_ASSIGN, '&', CAND); case '|': tok = S.Select3(OR, OR_ASSIGN, '|', COR); - default: tok = ILLEGAL; } } - end = S.pos - 1; - - /* - t.val = tok; - t.beg = beg; - t.end = end; - t.txt = S.src[beg : end]; - */ + end = S.pos - 1; // TODO correct? (Unicode) return tok, beg, end; } -- 2.48.1