From b1297aa04f72992186f75441ad2c34eddd829100 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 24 Nov 2008 18:24:21 -0800 Subject: [PATCH] - move error handling out of scanner - use more of the existing library code R=r OCL=19957 CL=19959 --- usr/gri/pretty/compilation.go | 89 ++++++++++++++++- usr/gri/pretty/scanner.go | 177 +++------------------------------- 2 files changed, 102 insertions(+), 164 deletions(-) diff --git a/usr/gri/pretty/compilation.go b/usr/gri/pretty/compilation.go index d52953f4b0..5c47d85f40 100644 --- a/usr/gri/pretty/compilation.go +++ b/usr/gri/pretty/compilation.go @@ -29,15 +29,100 @@ export type Flags struct { } +type ErrorHandler struct { + filename string; + src string; + nerrors int; + nwarnings int; + errpos int; + columns bool; +} + + +func (h *ErrorHandler) Init(filename, src string, columns bool) { + h.filename = filename; + h.src = src; + h.nerrors = 0; + h.nwarnings = 0; + h.errpos = 0; + h.columns = columns; +} + + +// Compute (line, column) information for a given source position. +func (h *ErrorHandler) LineCol(pos int) (line, col int) { + line = 1; + lpos := 0; + + src := h.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 (h *ErrorHandler) ErrorMsg(pos int, msg string) { + print(h.filename, ":"); + if pos >= 0 { + // print position + line, col := h.LineCol(pos); + print(line, ":"); + if h.columns { + print(col, ":"); + } + } + print(" ", msg, "\n"); + + h.nerrors++; + h.errpos = pos; + + if h.nerrors >= 10 { + sys.exit(1); + } +} + + +func (h *ErrorHandler) Error(pos int, msg string) { + // only report errors that are sufficiently far away from the previous error + // in the hope to avoid most follow-up errors + const errdist = 20; + delta := pos - h.errpos; // may be negative! + if delta < 0 { + delta = -delta; + } + + if delta > errdist || h.nerrors == 0 /* always report first error */ { + h.ErrorMsg(pos, msg); + } +} + + +func (h *ErrorHandler) Warning(pos int, msg string) { + panic("UNIMPLEMENTED"); +} + + export func Compile(src_file string, flags *Flags) (*AST.Program, int) { src, ok := Platform.ReadSourceFile(src_file); if !ok { print("cannot open ", src_file, "\n"); return nil, 1; } + + var err ErrorHandler; + err.Init(src_file, src, flags.columns); var scanner Scanner.Scanner; - scanner.Open(src_file, src, flags.columns, flags.testmode); + scanner.Init(&err, src, flags.testmode); var tstream *<-chan *Scanner.Token; if flags.tokenchan { @@ -48,7 +133,7 @@ export func Compile(src_file string, flags *Flags) (*AST.Program, int) { parser.Open(flags.verbose, flags.sixg, flags.deps, &scanner, tstream); prog := parser.ParseProgram(); - return prog, scanner.nerrors; + return prog, err.nerrors; } diff --git a/usr/gri/pretty/scanner.go b/usr/gri/pretty/scanner.go index 6aca9beb0f..b4df03f7e5 100644 --- a/usr/gri/pretty/scanner.go +++ b/usr/gri/pretty/scanner.go @@ -3,6 +3,8 @@ // license that can be found in the LICENSE file. package Scanner + +import "utf8" import Utils "utils" @@ -276,15 +278,17 @@ func digit_val(ch int) int { } +export type ErrorHandler interface { + Error(pos int, msg string); + Warning(pos int, msg string); +} + + export type Scanner struct { - // error handling - filename string; // error reporting only - nerrors int; // number of errors - errpos int; // last error position - columns bool; // if set, print columns in error messages + err ErrorHandler; // scanning - src string; // scanned source + src string; // source pos int; // current reading position ch int; // one char look-ahead chpos int; // position of ch @@ -304,7 +308,7 @@ func (S *Scanner) Next() { r, w := int(S.src[S.pos]), 1; if r >= 0x80 { // not ascii - r, w = sys.stringtorune(S.src, S.pos); + r, w = utf8.DecodeRuneInString(S.src, S.pos); } S.ch = r; S.chpos = S.pos; @@ -313,144 +317,6 @@ func (S *Scanner) Next() { S.ch = -1; // eof S.chpos = len(S.src); } -/* - const ( - Bit1 = 7; - Bitx = 6; - Bit2 = 5; - Bit3 = 4; - Bit4 = 3; - - T1 = (1 << (Bit1 + 1) - 1) ^ 0xFF; // 0000 0000 - Tx = (1 << (Bitx + 1) - 1) ^ 0xFF; // 1000 0000 - T2 = (1 << (Bit2 + 1) - 1) ^ 0xFF; // 1100 0000 - T3 = (1 << (Bit3 + 1) - 1) ^ 0xFF; // 1110 0000 - T4 = (1 << (Bit4 + 1) - 1) ^ 0xFF; // 1111 0000 - - Rune1 = 1 << (Bit1 + 0*Bitx) - 1; // 0000 0000 0111 1111 - Rune2 = 1 << (Bit2 + 1*Bitx) - 1; // 0000 0111 1111 1111 - Rune3 = 1 << (Bit3 + 2*Bitx) - 1; // 1111 1111 1111 1111 - - Maskx = 0x3F; // 1 << Bitx - 1; // 0011 1111 - Testx = 0xC0; // Maskx ^ 0xFF; // 1100 0000 - - Bad = 0xFFFD; // Runeerror - ); - - src := S.src; - lim := len(src); - pos := S.pos; - - // 1-byte sequence - // 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; - } - - // 2-byte sequence - // 0080-07FF => T2 Tx - if pos >= lim { - goto bad; - } - c1 := int(src[pos]) ^ Tx; - pos++; - if c1 & Testx != 0 { - goto bad; - } - if c0 < T3 { - if c0 < T2 { - goto bad; - } - r := (c0 << Bitx | c1) & Rune2; - if r <= Rune1 { - goto bad; - } - S.ch = r; - S.chpos = S.pos; - S.pos = pos; - return; - } - - // 3-byte sequence - // 0800-FFFF => T3 Tx Tx - if pos >= lim { - goto bad; - } - c2 := int(src[pos]) ^ Tx; - pos++; - if c2 & Testx != 0 { - goto bad; - } - if c0 < T4 { - r := (((c0 << Bitx | c1) << Bitx) | c2) & Rune3; - if r <= Rune2 { - goto bad; - } - S.ch = r; - S.chpos = S.pos; - S.pos = pos; - return; - } - - // bad encoding -bad: - S.ch = Bad; - S.chpos = S.pos; - S.pos += 1; - return; -*/ -} - - -// 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) ErrorMsg(pos int, msg string) { - print(S.filename, ":"); - if pos >= 0 { - // print position - line, col := S.LineCol(pos); - print(line, ":"); - if S.columns { - print(col, ":"); - } - } - print(" ", msg, "\n"); - - S.nerrors++; - S.errpos = pos; - - if S.nerrors >= 10 { - sys.exit(1); - } } @@ -464,17 +330,7 @@ func (S *Scanner) Error(pos int, msg string) { return; } - // only report errors that are sufficiently far away from the previous error - // in the hope to avoid most follow-up errors - const errdist = 20; - delta := pos - S.errpos; // may be negative! - if delta < 0 { - delta = -delta; - } - - if delta > errdist || S.nerrors == 0 /* always report first error */ { - S.ErrorMsg(pos, msg); - } + S.err.Error(pos, msg); } @@ -485,11 +341,8 @@ func (S *Scanner) ExpectNoErrors() { } -func (S *Scanner) Open(filename, src string, columns, testmode bool) { - S.filename = filename; - S.nerrors = 0; - S.errpos = 0; - S.columns = columns; +func (S *Scanner) Init(err ErrorHandler, src string, testmode bool) { + S.err = err; S.src = src; S.pos = 0; @@ -600,7 +453,7 @@ exit: if 0 <= oldpos && oldpos <= len(S.src) { // the previous error was not found - S.ErrorMsg(oldpos, "ERROR not found"); + S.Error(oldpos, "ERROR not found"); // TODO this should call ErrorMsg } } -- 2.48.1