summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2008-07-09 16:23:48 -0700
committerRobert Griesemer <gri@golang.org>2008-07-09 16:23:48 -0700
commit3e1172f413631086870446730f1e0c6e2fdd14d8 (patch)
treec4fd8fc3dc98ddd7e23d790d30cc96c974953f11
parent52568d750a77448c7d1a96fd450d672ffd7a1ee9 (diff)
downloadgolang-3e1172f413631086870446730f1e0c6e2fdd14d8.tar.gz
- initial better error reporting
SVN=126578
-rw-r--r--usr/gri/src/parser.go2
-rw-r--r--usr/gri/src/scanner.go45
2 files changed, 39 insertions, 8 deletions
diff --git a/usr/gri/src/parser.go b/usr/gri/src/parser.go
index e811fc8e7..b14c77805 100644
--- a/usr/gri/src/parser.go
+++ b/usr/gri/src/parser.go
@@ -64,7 +64,7 @@ func (P *Parser) Open(S *Scanner.Scanner, verbose int) {
func (P *Parser) Error(msg string) {
- panic "error: ", msg, "\n";
+ P.S.Error(P.S.pos, msg);
P.Next(); // make progress
}
diff --git a/usr/gri/src/scanner.go b/usr/gri/src/scanner.go
index 0ce6eca40..62798295d 100644
--- a/usr/gri/src/scanner.go
+++ b/usr/gri/src/scanner.go
@@ -376,11 +376,39 @@ func Init () {
}
+// Compute (line, column) information for a given source position.
+func (S *Scanner) LineCol(pos int) (line, col int) {
+ line = 1;
+ lpos := 0;
+
+ src := S.src;
+ if pos > len(src) {
+ pos = len(src);
+ }
+
+ for i := 0; i < pos; i++ {
+ if src[i] != '\n' {
+ line++;
+ lpos = i;
+ }
+ }
+
+ return line, pos - lpos;
+}
+
+
+func (S *Scanner) Error(pos int, msg string) {
+ line, col := S.LineCol(pos);
+ print "error ", line, ":", col, ": ", msg, "\n";
+}
+
+
func (S *Scanner) Open (src string) {
if Keywords == nil {
Init();
}
+ //S.nerrors = 0;
S.src = src;
S.pos = 0;
S.Next();
@@ -389,9 +417,9 @@ func (S *Scanner) Open (src string) {
func (S *Scanner) Expect (ch int) {
if S.ch != ch {
- panic "expected ", string(ch), " found ", string(S.ch);
+ S.Error(S.pos, "expected " + string(ch) + ", found " + string(S.ch));
}
- S.Next();
+ S.Next(); // make always progress
}
@@ -412,6 +440,7 @@ func (S *Scanner) SkipComment () {
} else {
/* comment */
+ pos := S.pos;
S.Next();
for S.ch >= 0 {
ch := S.ch;
@@ -421,7 +450,7 @@ func (S *Scanner) SkipComment () {
return;
}
}
- panic "comment not terminated";
+ S.Error(pos, "comment not terminated");
}
}
@@ -505,7 +534,7 @@ func (S *Scanner) ScanDigits(n int, base int) {
n--;
}
if n > 0 {
- panic "illegal char escape";
+ S.Error(S.pos, "illegal char escape");
}
}
@@ -536,7 +565,7 @@ func (S *Scanner) ScanEscape () string {
return ""; // TODO fix this
default:
- panic "illegal char escape";
+ S.Error(S.pos, "illegal char escape");
}
}
@@ -558,11 +587,12 @@ func (S *Scanner) ScanChar () int {
func (S *Scanner) ScanString () int {
// '"' already consumed
+ pos := S.pos - 1; // TODO maybe incorrect (Unicode)
for S.ch != '"' {
ch := S.ch;
S.Next();
if ch == '\n' || ch < 0 {
- panic "string not terminated";
+ S.Error(pos, "string not terminated");
}
if ch == '\\' {
S.ScanEscape();
@@ -577,11 +607,12 @@ func (S *Scanner) ScanString () int {
func (S *Scanner) ScanRawString () int {
// '`' already consumed
+ pos := S.pos - 1; // TODO maybe incorrect (Unicode)
for S.ch != '`' {
ch := S.ch;
S.Next();
if ch == '\n' || ch < 0 {
- panic "string not terminated";
+ S.Error(pos, "string not terminated");
}
}