Commit a010d45c authored by Robert Griesemer's avatar Robert Griesemer

- adjust to new scanner interface (pass filename to Init)

- delete error handling code which is not needed anymore

R=rsc
DELTA=83  (0 added, 65 deleted, 18 changed)
OCL=31572
CL=31602
parent 14228f38
...@@ -22,45 +22,6 @@ import ( ...@@ -22,45 +22,6 @@ import (
) )
// A parser error is represented by an Error node. The position Pos, if
// valid, points to the beginning of the offending token, and the error
// condition is described by Msg.
//
type Error struct {
Pos token.Position;
Msg string;
}
func (e *Error) String() string {
pos := "";
if e.Pos.IsValid() {
pos = fmt.Sprintf("%d:%d: ", e.Pos.Line, e.Pos.Column);
}
return pos + e.Msg;
}
// Parser errors are returned as an ErrorList.
type ErrorList []*Error
// ErrorList implements the SortInterface.
func (p ErrorList) Len() int { return len(p); }
func (p ErrorList) Swap(i, j int) { p[i], p[j] = p[j], p[i]; }
func (p ErrorList) Less(i, j int) bool { return p[i].Pos.Offset < p[j].Pos.Offset; }
func (p ErrorList) String() string {
switch len(p) {
case 0: return "unspecified error";
case 1: return p[0].String();
}
return fmt.Sprintf("%s (and %d more errors)", p[0].String(), len(p) - 1);
}
// Names to index the parser's commentIndex array. // Names to index the parser's commentIndex array.
const ( const (
leading = iota; // index of the leading comments entry leading = iota; // index of the leading comments entry
...@@ -74,7 +35,7 @@ var noIndex = [2]int{-1, -1}; ...@@ -74,7 +35,7 @@ var noIndex = [2]int{-1, -1};
// The parser structure holds the parser's internal state. // The parser structure holds the parser's internal state.
type parser struct { type parser struct {
errors vector.Vector; scanner.ErrorVector;
scanner scanner.Scanner; scanner scanner.Scanner;
// Tracing/debugging // Tracing/debugging
...@@ -263,17 +224,6 @@ func (p *parser) getComment(kind int) *ast.CommentGroup { ...@@ -263,17 +224,6 @@ func (p *parser) getComment(kind int) *ast.CommentGroup {
} }
// The parser implements scanner.Error.
func (p *parser) Error(pos token.Position, msg string) {
// Don't collect errors that are on the same line as the previous error
// in the hope to reduce the number of spurious errors due to incorrect
// parser synchronization.
if p.errors.Len() == 0 || p.errors.Last().(*Error).Pos.Line != pos.Line {
p.errors.Push(&Error{pos, msg});
}
}
func (p *parser) errorExpected(pos token.Position, msg string) { func (p *parser) errorExpected(pos token.Position, msg string) {
msg = "expected " + msg; msg = "expected " + msg;
if pos.Offset == p.pos.Offset { if pos.Offset == p.pos.Offset {
...@@ -1951,7 +1901,7 @@ func (p *parser) parsePackage() *ast.Program { ...@@ -1951,7 +1901,7 @@ func (p *parser) parsePackage() *ast.Program {
// Don't bother parsing the rest if we had errors already. // Don't bother parsing the rest if we had errors already.
// Likely not a Go source file at all. // Likely not a Go source file at all.
if p.errors.Len() == 0 && p.mode & PackageClauseOnly == 0 { if p.ErrorCount() == 0 && p.mode & PackageClauseOnly == 0 {
// import decls // import decls
list := vector.New(0); list := vector.New(0);
for p.tok == token.IMPORT { for p.tok == token.IMPORT {
...@@ -2032,15 +1982,15 @@ func scannerMode(mode uint) uint { ...@@ -2032,15 +1982,15 @@ func scannerMode(mode uint) uint {
} }
func (p *parser) init(src interface{}, mode uint) os.Error { func (p *parser) init(filename string, src interface{}, mode uint) os.Error {
data, err := readSource(src); data, err := readSource(src);
if err != nil { if err != nil {
return err; return err;
} }
// initialize parser state // initialize parser state
p.errors.Init(0); p.ErrorVector.Init();
p.scanner.Init(data, p, scannerMode(mode)); p.scanner.Init(filename, data, p, scannerMode(mode));
p.mode = mode; p.mode = mode;
p.trace = mode & Trace != 0; // for convenience (p.trace is used frequently) p.trace = mode & Trace != 0; // for convenience (p.trace is used frequently)
p.comments.Init(0); p.comments.Init(0);
...@@ -2051,21 +2001,6 @@ func (p *parser) init(src interface{}, mode uint) os.Error { ...@@ -2051,21 +2001,6 @@ func (p *parser) init(src interface{}, mode uint) os.Error {
} }
// errorList converts parsing errors to an errors list. Returns nil
// if there are no errors.
func (p *parser) errorList() os.Error {
if p.errors.Len() == 0 {
return nil;
}
errors := make(ErrorList, p.errors.Len());
for i := 0; i < p.errors.Len(); i++ {
errors[i] = p.errors.At(i).(*Error);
}
return errors;
}
// Parse parses a Go program. // Parse parses a Go program.
// //
// The program source src may be provided in a variety of formats. At the // The program source src may be provided in a variety of formats. At the
...@@ -2080,47 +2015,47 @@ func (p *parser) errorList() os.Error { ...@@ -2080,47 +2015,47 @@ func (p *parser) errorList() os.Error {
// representing the fragments of erroneous source code) and an ErrorList // representing the fragments of erroneous source code) and an ErrorList
// describing the syntax errors. // describing the syntax errors.
// //
func Parse(src interface{}, mode uint) (*ast.Program, os.Error) { func Parse(filename string, src interface{}, mode uint) (*ast.Program, os.Error) {
var p parser; var p parser;
if err := p.init(src, mode); err != nil { if err := p.init(filename, src, mode); err != nil {
return nil, err; return nil, err;
} }
prog := p.parsePackage(); prog := p.parsePackage();
return prog, p.errorList(); return prog, p.GetError(scanner.NoMultiples);
} }
// ParseStmts parses a list of Go statement. // ParseStmts parses a list of Go statement.
func ParseStmts(src interface{}, mode uint) ([]ast.Stmt, os.Error) { func ParseStmts(filename string, src interface{}, mode uint) ([]ast.Stmt, os.Error) {
if mode & (PackageClauseOnly | ImportsOnly) != 0 { if mode & (PackageClauseOnly | ImportsOnly) != 0 {
return nil, nil; return nil, nil;
} }
var p parser; var p parser;
if err := p.init(src, mode); err != nil { if err := p.init(filename, src, mode); err != nil {
return nil, err; return nil, err;
} }
stmts := p.parseStatementList(); stmts := p.parseStatementList();
return stmts, p.errorList(); return stmts, p.GetError(scanner.Sorted);
} }
// ParseExpr parses a single Go expression. // ParseExpr parses a single Go expression.
func ParseExpr(src interface{}, mode uint) (ast.Expr, os.Error) { func ParseExpr(filename string, src interface{}, mode uint) (ast.Expr, os.Error) {
if mode & (PackageClauseOnly | ImportsOnly) != 0 { if mode & (PackageClauseOnly | ImportsOnly) != 0 {
return nil, nil; return nil, nil;
} }
var p parser; var p parser;
if err := p.init(src, mode); err != nil { if err := p.init(filename, src, mode); err != nil {
return nil, err; return nil, err;
} }
expr := p.parseExpression(); expr := p.parseExpression();
return expr, p.errorList(); return expr, p.GetError(scanner.Sorted);
} }
...@@ -22,7 +22,7 @@ var illegalInputs = []interface{} { ...@@ -22,7 +22,7 @@ var illegalInputs = []interface{} {
func TestParseIllegalInputs(t *testing.T) { func TestParseIllegalInputs(t *testing.T) {
for _, src := range illegalInputs { for _, src := range illegalInputs {
prog, err := Parse(src, 0); prog, err := Parse("", src, 0);
if err == nil { if err == nil {
t.Errorf("Parse(%v) should have failed", src); t.Errorf("Parse(%v) should have failed", src);
} }
...@@ -38,7 +38,7 @@ var validPrograms = []interface{} { ...@@ -38,7 +38,7 @@ var validPrograms = []interface{} {
func TestParseValidPrograms(t *testing.T) { func TestParseValidPrograms(t *testing.T) {
for _, src := range validPrograms { for _, src := range validPrograms {
prog, err := Parse(src, 0); prog, err := Parse("", src, 0);
if err != nil { if err != nil {
t.Errorf("Parse(%q) failed: %v", src, err); t.Errorf("Parse(%q) failed: %v", src, err);
} }
...@@ -60,7 +60,7 @@ func TestParse3(t *testing.T) { ...@@ -60,7 +60,7 @@ func TestParse3(t *testing.T) {
t.Fatal(err); t.Fatal(err);
} }
prog, err := Parse(src, 0); prog, err := Parse(filename, src, 0);
if err != nil { if err != nil {
t.Errorf("Parse(%s): %v", filename, err); t.Errorf("Parse(%s): %v", filename, err);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment