mirror of
https://github.com/golang/go.git
synced 2025-05-23 16:31:27 +00:00
- incorporation of suggestions by rsc
R=rsc OCL=26959 CL=26959
This commit is contained in:
parent
dc5b4678e2
commit
3f42f44227
@ -49,16 +49,14 @@ func (list ErrorList) Swap(i, j int) { list[i], list[j] = list[j], list[i]; }
|
|||||||
|
|
||||||
type errorHandler struct {
|
type errorHandler struct {
|
||||||
filename string;
|
filename string;
|
||||||
src []byte;
|
|
||||||
columns bool;
|
columns bool;
|
||||||
errline int;
|
errline int;
|
||||||
errors vector.Vector;
|
errors vector.Vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (h *errorHandler) Init(filename string, src []byte, columns bool) {
|
func (h *errorHandler) Init(filename string, columns bool) {
|
||||||
h.filename = filename;
|
h.filename = filename;
|
||||||
h.src = src;
|
|
||||||
h.columns = columns;
|
h.columns = columns;
|
||||||
h.errors.Init(0);
|
h.errors.Init(0);
|
||||||
}
|
}
|
||||||
@ -84,26 +82,24 @@ func (h *errorHandler) Error(pos token.Position, msg string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Compile(src_file string, flags *Flags) (*ast.Package, ErrorList) {
|
func Compile(filename string, flags *Flags) (*ast.Package, ErrorList) {
|
||||||
src, ok := Platform.ReadSourceFile(src_file);
|
src, os_err := os.Open(filename, os.O_RDONLY, 0);
|
||||||
if !ok {
|
defer src.Close();
|
||||||
print("cannot open ", src_file, "\n");
|
if os_err != nil {
|
||||||
|
fmt.Printf("cannot open %s (%s)\n", filename, os_err.String());
|
||||||
return nil, nil;
|
return nil, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
var err errorHandler;
|
var err errorHandler;
|
||||||
err.Init(src_file, src, flags.Columns);
|
err.Init(filename, flags.Columns);
|
||||||
|
|
||||||
var scanner scanner.Scanner;
|
mode := parser.ParseComments;
|
||||||
scanner.Init(src, &err, true);
|
|
||||||
|
|
||||||
mode := uint(0);
|
|
||||||
if flags.Verbose {
|
if flags.Verbose {
|
||||||
mode |= parser.Trace;
|
mode |= parser.Trace;
|
||||||
}
|
}
|
||||||
prog, nerrs := parser.Parse(&scanner, &err, mode);
|
prog, ok2 := parser.Parse(src, &err, mode);
|
||||||
|
|
||||||
if err.errors.Len() == 0 {
|
if ok2 {
|
||||||
TypeChecker.CheckProgram(&err, prog);
|
TypeChecker.CheckProgram(&err, prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,24 +10,15 @@
|
|||||||
package parser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt";
|
|
||||||
"vector";
|
|
||||||
"token";
|
|
||||||
"ast";
|
"ast";
|
||||||
|
"fmt";
|
||||||
|
"io";
|
||||||
|
"scanner";
|
||||||
|
"token";
|
||||||
|
"vector";
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// An implementation of a Scanner must be provided to the Parser.
|
|
||||||
// The parser calls Scan() repeatedly until token.EOF is returned.
|
|
||||||
// Scan must return the current token position pos, the token value
|
|
||||||
// tok, and the corresponding token literal string lit; lit can be
|
|
||||||
// undefined/nil unless the token is a literal (tok.IsLiteral() == true).
|
|
||||||
//
|
|
||||||
type Scanner interface {
|
|
||||||
Scan() (pos token.Position, tok token.Token, lit []byte);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// An implementation of an ErrorHandler may be provided to the parser.
|
// An implementation of an ErrorHandler may be provided to the parser.
|
||||||
// If a syntax error is encountered and a handler was installed, Error
|
// If a syntax error is encountered and a handler was installed, Error
|
||||||
// is called with a position and an error message. The position points
|
// is called with a position and an error message. The position points
|
||||||
@ -45,7 +36,7 @@ type interval struct {
|
|||||||
|
|
||||||
// The parser structure holds the parser's internal state.
|
// The parser structure holds the parser's internal state.
|
||||||
type parser struct {
|
type parser struct {
|
||||||
scanner Scanner;
|
scanner scanner.Scanner;
|
||||||
err ErrorHandler; // nil if no handler installed
|
err ErrorHandler; // nil if no handler installed
|
||||||
errorCount int;
|
errorCount int;
|
||||||
|
|
||||||
@ -81,11 +72,10 @@ func (p *parser) printTrace(a ...) {
|
|||||||
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
|
||||||
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ";
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ";
|
||||||
const n = uint(len(dots));
|
const n = uint(len(dots));
|
||||||
|
|
||||||
fmt.Printf("%5d:%3d: ", p.pos.Line, p.pos.Column);
|
fmt.Printf("%5d:%3d: ", p.pos.Line, p.pos.Column);
|
||||||
i := 2*p.indent;
|
i := 2*p.indent;
|
||||||
for ; i > n; i -= n {
|
for ; i > n; i -= n {
|
||||||
fmt.Print(dots[0 : i%n]);
|
fmt.Print(dots);
|
||||||
}
|
}
|
||||||
fmt.Print(dots[0 : i]);
|
fmt.Print(dots[0 : i]);
|
||||||
fmt.Println(a);
|
fmt.Println(a);
|
||||||
@ -1847,13 +1837,14 @@ func (p *parser) parseDeclaration() ast.Decl {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Packages
|
// Packages
|
||||||
|
|
||||||
// A set of flags (or 0) must be provided via the mode parameter to
|
// The mode parameter to the Parse function is a set of flags (or 0).
|
||||||
// the Parse function. They control the amount of source code parsed
|
// They control the amount of source code parsed and other optional
|
||||||
// and other optional parser functionality.
|
// parser functionality.
|
||||||
//
|
//
|
||||||
const (
|
const (
|
||||||
PackageClauseOnly = 1 << iota; // parsing stops after package clause
|
PackageClauseOnly uint = 1 << iota; // parsing stops after package clause
|
||||||
ImportsOnly; // parsing stops after import declarations
|
ImportsOnly; // parsing stops after import declarations
|
||||||
|
ParseComments; // parse comments and add them to AST
|
||||||
Trace; // print a trace of parsed productions
|
Trace; // print a trace of parsed productions
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1914,29 +1905,57 @@ func (p *parser) parsePackage() *ast.Package {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Parsing of entire programs.
|
// Parsing of entire programs.
|
||||||
|
|
||||||
// Parse invokes the Go parser. It calls the scanner's Scan method repeatedly
|
func readSource(src interface{}, err ErrorHandler) []byte {
|
||||||
// to obtain a token sequence which is parsed according to Go syntax. If an
|
errmsg := "could not read input src";
|
||||||
// error handler is provided (err != nil), it is invoked for each syntax error
|
|
||||||
// encountered.
|
switch s := src.(type) {
|
||||||
|
case string:
|
||||||
|
return io.StringBytes(s);
|
||||||
|
case []byte:
|
||||||
|
return s;
|
||||||
|
case *io.ByteBuffer:
|
||||||
|
// is io.Read, but src is already available in []byte form
|
||||||
|
if s != nil {
|
||||||
|
return s.Data();
|
||||||
|
}
|
||||||
|
case io.Read:
|
||||||
|
var buf io.ByteBuffer;
|
||||||
|
n, os_err := io.Copy(s, &buf);
|
||||||
|
if os_err == nil {
|
||||||
|
return buf.Data();
|
||||||
|
}
|
||||||
|
errmsg = os_err.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
err.Error(noPos, errmsg);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parse parses a Go program.
|
||||||
//
|
//
|
||||||
// Parse returns an AST and the number of syntax errors encountered. If the
|
// The program source src may be provided in a variety of formats. At the
|
||||||
// error count is 0, the result is the correct AST for the token sequence
|
// moment the following types are supported: string, []byte, and io.Read.
|
||||||
// returned by the scanner (*). If the error count is > 0, the AST may only
|
|
||||||
// be constructed partially, with ast.BadX nodes representing the fragments
|
|
||||||
// of source code that contained syntax errors.
|
|
||||||
//
|
//
|
||||||
// The mode parameter controls the amount of source text parsed and other
|
// The ErrorHandler err, if not nil, is invoked if src cannot be read and
|
||||||
// optional parser functionality.
|
// for each syntax error found. The mode parameter controls the amount of
|
||||||
|
// source text parsed and other optional parser functionality.
|
||||||
//
|
//
|
||||||
// (*) Note that a scanner may find lexical syntax errors but still return
|
// Parse returns an AST and the boolean value true if no errors occured;
|
||||||
// a legal token sequence. To be sure there are no syntax errors in the
|
// it returns a partial AST (or nil if the source couldn't be read) and
|
||||||
// source (and not just the token sequence corresponding to the source)
|
// the boolean value false to indicate failure.
|
||||||
// both the parser and scanner error count must be 0.
|
|
||||||
//
|
//
|
||||||
func Parse(scanner Scanner, err ErrorHandler, mode uint) (*ast.Package, int) {
|
// If syntax errors were found, the AST may only be constructed partially,
|
||||||
|
// with ast.BadX nodes representing the fragments of erroneous source code.
|
||||||
|
//
|
||||||
|
func Parse(src interface{}, err ErrorHandler, mode uint) (*ast.Package, bool) {
|
||||||
|
data := readSource(src, err);
|
||||||
|
|
||||||
// initialize parser state
|
// initialize parser state
|
||||||
var p parser;
|
var p parser;
|
||||||
p.scanner = scanner;
|
p.scanner.Init(data, err, mode & ParseComments != 0);
|
||||||
p.err = err;
|
p.err = err;
|
||||||
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)
|
||||||
@ -1944,6 +1963,6 @@ func Parse(scanner Scanner, err ErrorHandler, mode uint) (*ast.Package, int) {
|
|||||||
p.next();
|
p.next();
|
||||||
|
|
||||||
// parse program
|
// parse program
|
||||||
pak := p.parsePackage();
|
prog := p.parsePackage();
|
||||||
return pak, p.errorCount;
|
return prog, p.scanner.ErrorCount == 0 && p.errorCount == 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user