]> Cypherpunks repositories - gostls13.git/commitdiff
- initial better error reporting
authorRobert Griesemer <gri@golang.org>
Wed, 9 Jul 2008 23:23:48 +0000 (16:23 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 9 Jul 2008 23:23:48 +0000 (16:23 -0700)
SVN=126578

usr/gri/src/parser.go
usr/gri/src/scanner.go

index e811fc8e72ba720c4b2c17af4a6cfeb60cd0f0d8..b14c7780566357d0bf7cd8e54482c609b9083489 100644 (file)
@@ -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
 }
 
index 0ce6eca403aa35228c00b84a869409d8e86ccf77..62798295d0c4f58a29c0c3dfb048a227b0293596 100644 (file)
@@ -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");
                }
        }