summaryrefslogtreecommitdiff
path: root/usr/gri/pretty/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'usr/gri/pretty/parser.go')
-rw-r--r--usr/gri/pretty/parser.go313
1 files changed, 173 insertions, 140 deletions
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index d1de483b1..073fd2a01 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -6,37 +6,54 @@
// provided via the Scanner interface. The output is an abstract syntax
// tree (AST) representing the Go source.
//
-// A client may parse the entire program (ParseProgram), only the package
-// clause (ParsePackageClause), or the package clause and the import
-// declarations (ParseImportDecls).
-//
-package Parser
+package parser
import (
"fmt";
"vector";
"token";
- "scanner";
"ast";
)
-// TODO rename Position to scanner.Position, possibly factor out
-type Position scanner.Location
-
-
type interval struct {
beg, end int;
}
-// A Parser holds the parser's internal state while processing
-// a given text. It can be allocated as part of another data
-// structure but must be initialized via Init before use.
+// 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 if the token
+// is a literal (i.e., if tok.IsLiteral() is true).
+//
+type Scanner interface {
+ Scan() (pos token.Position, tok token.Token, lit []byte);
+}
+
+
+// An implementation of an ErrorHandler must be provided to the parser.
+// If a syntax error is encountered, Error is called with a position and
+// an error message. The position points to the beginning of the offending
+// token.
//
-type Parser struct {
- scanner *scanner.Scanner;
- err scanner.ErrorHandler;
+type ErrorHandler interface {
+ Error(pos token.Position, msg string);
+}
+
+
+// The following flags control optional parser functionality. A set of
+// flags (or 0) must be provided as a parameter to the Parse function.
+//
+const (
+ Trace = 1 << iota;
+)
+
+
+// The parser structure holds the parser's internal state.
+type parser struct {
+ scanner Scanner;
+ err ErrorHandler;
// Tracing/debugging
trace bool;
@@ -46,9 +63,9 @@ type Parser struct {
last_doc interval; // last comments interval of consecutive comments
// The next token
- pos Position; // token location
+ pos token.Position; // token location
tok token.Token; // one token look-ahead
- val []byte; // token value
+ lit []byte; // token literal
// Non-syntactic parser control
opt_semi bool; // true if semicolon separator is optional in statement list
@@ -58,7 +75,7 @@ type Parser struct {
// When we don't have a location use nopos.
// TODO make sure we always have a location.
-var nopos Position;
+var nopos token.Position;
// ----------------------------------------------------------------------------
@@ -72,7 +89,7 @@ func unreachable() {
// ----------------------------------------------------------------------------
// Parsing support
-func (P *Parser) printIndent() {
+func (P *parser) printIndent() {
i := P.indent;
// reduce printing time by a factor of 2 or more
for ; i > 10; i -= 10 {
@@ -84,7 +101,7 @@ func (P *Parser) printIndent() {
}
-func trace(P *Parser, msg string) *Parser {
+func trace(P *parser, msg string) *parser {
P.printIndent();
fmt.Printf("%s (\n", msg);
P.indent++;
@@ -92,30 +109,30 @@ func trace(P *Parser, msg string) *Parser {
}
-func un/*trace*/(P *Parser) {
+func un/*trace*/(P *parser) {
P.indent--;
P.printIndent();
fmt.Printf(")\n");
}
-func (P *Parser) next0() {
- P.pos, P.tok, P.val = P.scanner.Scan();
+func (P *parser) next0() {
+ P.pos, P.tok, P.lit = P.scanner.Scan();
P.opt_semi = false;
if P.trace {
P.printIndent();
switch P.tok {
case token.IDENT, token.INT, token.FLOAT, token.CHAR, token.STRING:
- fmt.Printf("%d:%d: %s = %s\n", P.pos.Line, P.pos.Col, P.tok.String(), P.val);
+ fmt.Printf("%d:%d: %s = %s\n", P.pos.Line, P.pos.Column, P.tok.String(), P.lit);
case token.LPAREN:
// don't print '(' - screws up selection in terminal window
- fmt.Printf("%d:%d: LPAREN\n", P.pos.Line, P.pos.Col);
+ fmt.Printf("%d:%d: LPAREN\n", P.pos.Line, P.pos.Column);
case token.RPAREN:
// don't print ')' - screws up selection in terminal window
- fmt.Printf("%d:%d: RPAREN\n", P.pos.Line, P.pos.Col);
+ fmt.Printf("%d:%d: RPAREN\n", P.pos.Line, P.pos.Column);
default:
- fmt.Printf("%d:%d: %s\n", P.pos.Line, P.pos.Col, P.tok.String());
+ fmt.Printf("%d:%d: %s\n", P.pos.Line, P.pos.Column, P.tok.String());
}
}
}
@@ -123,27 +140,27 @@ func (P *Parser) next0() {
// Collect a comment in the parser's comment list and return the line
// on which the comment ends.
-func (P *Parser) collectComment() int {
+func (P *parser) collectComment() int {
// For /*-style comments, the comment may end on a different line.
// Scan the comment for '\n' chars and adjust the end line accordingly.
// (Note that the position of the next token may be even further down
// as there may be more whitespace lines after the comment.)
endline := P.pos.Line;
- if P.val[1] == '*' {
- for i, b := range P.val {
+ if P.lit[1] == '*' {
+ for i, b := range P.lit {
if b == '\n' {
endline++;
}
}
}
- P.comments.Push(&ast.Comment{P.pos, P.val, endline});
+ P.comments.Push(&ast.Comment{P.pos, P.lit, endline});
P.next0();
return endline;
}
-func (P *Parser) getComments() interval {
+func (P *parser) getComments() interval {
// group adjacent comments, an empty line terminates a group
beg := P.comments.Len();
endline := P.pos.Line;
@@ -155,7 +172,7 @@ func (P *Parser) getComments() interval {
}
-func (P *Parser) next() {
+func (P *parser) next() {
P.next0();
P.last_doc = interval{0, 0};
for P.tok == token.COMMENT {
@@ -164,25 +181,16 @@ func (P *Parser) next() {
}
-func (P *Parser) Init(scanner *scanner.Scanner, err scanner.ErrorHandler, trace bool) {
- P.scanner = scanner;
- P.err = err;
- P.trace = trace;
- P.comments.Init(0);
- P.next();
-}
-
-
-func (P *Parser) error(pos Position, msg string) {
+func (P *parser) error(pos token.Position, msg string) {
P.err.Error(pos, msg);
}
-func (P *Parser) expect(tok token.Token) Position {
+func (P *parser) expect(tok token.Token) token.Position {
if P.tok != tok {
msg := "expected '" + tok.String() + "', found '" + P.tok.String() + "'";
if P.tok.IsLiteral() {
- msg += " " + string(P.val);
+ msg += " " + string(P.lit);
}
P.error(P.pos, msg);
}
@@ -192,7 +200,7 @@ func (P *Parser) expect(tok token.Token) Position {
}
-func (P *Parser) getDoc() ast.Comments {
+func (P *parser) getDoc() ast.Comments {
doc := P.last_doc;
n := doc.end - doc.beg;
@@ -217,19 +225,19 @@ func (P *Parser) getDoc() ast.Comments {
// ----------------------------------------------------------------------------
// Common productions
-func (P *Parser) tryType() ast.Expr;
-func (P *Parser) parseExpression(prec int) ast.Expr;
-func (P *Parser) parseStatement() ast.Stmt;
-func (P *Parser) parseDeclaration() ast.Decl;
+func (P *parser) tryType() ast.Expr;
+func (P *parser) parseExpression(prec int) ast.Expr;
+func (P *parser) parseStatement() ast.Stmt;
+func (P *parser) parseDeclaration() ast.Decl;
-func (P *Parser) parseIdent() *ast.Ident {
+func (P *parser) parseIdent() *ast.Ident {
if P.trace {
defer un(trace(P, "Ident"));
}
if P.tok == token.IDENT {
- x := &ast.Ident{P.pos, P.val};
+ x := &ast.Ident{P.pos, P.lit};
P.next();
return x;
}
@@ -239,7 +247,7 @@ func (P *Parser) parseIdent() *ast.Ident {
}
-func (P *Parser) parseIdentList(x ast.Expr) []*ast.Ident {
+func (P *parser) parseIdentList(x ast.Expr) []*ast.Ident {
if P.trace {
defer un(trace(P, "IdentList"));
}
@@ -264,7 +272,7 @@ func (P *Parser) parseIdentList(x ast.Expr) []*ast.Ident {
}
-func (P *Parser) parseExpressionList() []ast.Expr {
+func (P *parser) parseExpressionList() []ast.Expr {
if P.trace {
defer un(trace(P, "ExpressionList"));
}
@@ -289,7 +297,7 @@ func (P *Parser) parseExpressionList() []ast.Expr {
// ----------------------------------------------------------------------------
// Types
-func (P *Parser) parseType() ast.Expr {
+func (P *parser) parseType() ast.Expr {
if P.trace {
defer un(trace(P, "Type"));
}
@@ -304,7 +312,7 @@ func (P *Parser) parseType() ast.Expr {
}
-func (P *Parser) parseVarType() ast.Expr {
+func (P *parser) parseVarType() ast.Expr {
if P.trace {
defer un(trace(P, "VarType"));
}
@@ -313,7 +321,7 @@ func (P *Parser) parseVarType() ast.Expr {
}
-func (P *Parser) parseQualifiedIdent() ast.Expr {
+func (P *parser) parseQualifiedIdent() ast.Expr {
if P.trace {
defer un(trace(P, "QualifiedIdent"));
}
@@ -328,7 +336,7 @@ func (P *Parser) parseQualifiedIdent() ast.Expr {
}
-func (P *Parser) parseTypeName() ast.Expr {
+func (P *parser) parseTypeName() ast.Expr {
if P.trace {
defer un(trace(P, "TypeName"));
}
@@ -337,7 +345,7 @@ func (P *Parser) parseTypeName() ast.Expr {
}
-func (P *Parser) parseArrayType() *ast.ArrayType {
+func (P *parser) parseArrayType() *ast.ArrayType {
if P.trace {
defer un(trace(P, "ArrayType"));
}
@@ -357,7 +365,7 @@ func (P *Parser) parseArrayType() *ast.ArrayType {
}
-func (P *Parser) parseChannelType() *ast.ChannelType {
+func (P *parser) parseChannelType() *ast.ChannelType {
if P.trace {
defer un(trace(P, "ChannelType"));
}
@@ -381,7 +389,7 @@ func (P *Parser) parseChannelType() *ast.ChannelType {
}
-func (P *Parser) tryParameterType() ast.Expr {
+func (P *parser) tryParameterType() ast.Expr {
if P.tok == token.ELLIPSIS {
loc := P.pos;
P.next();
@@ -391,7 +399,7 @@ func (P *Parser) tryParameterType() ast.Expr {
}
-func (P *Parser) parseParameterType() ast.Expr {
+func (P *parser) parseParameterType() ast.Expr {
typ := P.tryParameterType();
if typ == nil {
P.error(P.pos, "type expected");
@@ -402,7 +410,7 @@ func (P *Parser) parseParameterType() ast.Expr {
}
-func (P *Parser) parseParameterDecl(ellipsis_ok bool) (*vector.Vector, ast.Expr) {
+func (P *parser) parseParameterDecl(ellipsis_ok bool) (*vector.Vector, ast.Expr) {
if P.trace {
defer un(trace(P, "ParameterDecl"));
}
@@ -426,7 +434,7 @@ func (P *Parser) parseParameterDecl(ellipsis_ok bool) (*vector.Vector, ast.Expr)
}
-func (P *Parser) parseParameterList(ellipsis_ok bool) []*ast.Field {
+func (P *parser) parseParameterList(ellipsis_ok bool) []*ast.Field {
if P.trace {
defer un(trace(P, "ParameterList"));
}
@@ -468,7 +476,7 @@ func (P *Parser) parseParameterList(ellipsis_ok bool) []*ast.Field {
// TODO make sure Go spec is updated
-func (P *Parser) parseParameters(ellipsis_ok bool) []*ast.Field {
+func (P *parser) parseParameters(ellipsis_ok bool) []*ast.Field {
if P.trace {
defer un(trace(P, "Parameters"));
}
@@ -484,7 +492,7 @@ func (P *Parser) parseParameters(ellipsis_ok bool) []*ast.Field {
}
-func (P *Parser) parseResult() []*ast.Field {
+func (P *parser) parseResult() []*ast.Field {
if P.trace {
defer un(trace(P, "Result"));
}
@@ -510,7 +518,7 @@ func (P *Parser) parseResult() []*ast.Field {
// (params) type
// (params) (results)
-func (P *Parser) parseSignature() (params []*ast.Field, results []*ast.Field) {
+func (P *parser) parseSignature() (params []*ast.Field, results []*ast.Field) {
if P.trace {
defer un(trace(P, "Signature"));
}
@@ -522,7 +530,7 @@ func (P *Parser) parseSignature() (params []*ast.Field, results []*ast.Field) {
}
-func (P *Parser) parseFunctionType() *ast.FunctionType {
+func (P *parser) parseFunctionType() *ast.FunctionType {
if P.trace {
defer un(trace(P, "FunctionType"));
}
@@ -534,7 +542,7 @@ func (P *Parser) parseFunctionType() *ast.FunctionType {
}
-func (P *Parser) parseMethodSpec() *ast.Field {
+func (P *parser) parseMethodSpec() *ast.Field {
if P.trace {
defer un(trace(P, "MethodSpec"));
}
@@ -557,13 +565,13 @@ func (P *Parser) parseMethodSpec() *ast.Field {
}
-func (P *Parser) parseInterfaceType() *ast.InterfaceType {
+func (P *parser) parseInterfaceType() *ast.InterfaceType {
if P.trace {
defer un(trace(P, "InterfaceType"));
}
pos := P.expect(token.INTERFACE);
- var lbrace, rbrace Position;
+ var lbrace, rbrace token.Position;
var methods []*ast.Field;
if P.tok == token.LBRACE {
lbrace = P.pos;
@@ -591,7 +599,7 @@ func (P *Parser) parseInterfaceType() *ast.InterfaceType {
}
-func (P *Parser) parseMapType() *ast.MapType {
+func (P *parser) parseMapType() *ast.MapType {
if P.trace {
defer un(trace(P, "MapType"));
}
@@ -606,9 +614,9 @@ func (P *Parser) parseMapType() *ast.MapType {
}
-func (P *Parser) parseStringList(x *ast.StringLit) []*ast.StringLit
+func (P *parser) parseStringList(x *ast.StringLit) []*ast.StringLit
-func (P *Parser) parseFieldDecl() *ast.Field {
+func (P *parser) parseFieldDecl() *ast.Field {
if P.trace {
defer un(trace(P, "FieldDecl"));
}
@@ -662,13 +670,13 @@ func (P *Parser) parseFieldDecl() *ast.Field {
}
-func (P *Parser) parseStructType() *ast.StructType {
+func (P *parser) parseStructType() *ast.StructType {
if P.trace {
defer un(trace(P, "StructType"));
}
pos := P.expect(token.STRUCT);
- var lbrace, rbrace Position;
+ var lbrace, rbrace token.Position;
var fields []*ast.Field;
if P.tok == token.LBRACE {
lbrace = P.pos;
@@ -701,7 +709,7 @@ func (P *Parser) parseStructType() *ast.StructType {
}
-func (P *Parser) parsePointerType() *ast.StarExpr {
+func (P *parser) parsePointerType() *ast.StarExpr {
if P.trace {
defer un(trace(P, "PointerType"));
}
@@ -713,7 +721,7 @@ func (P *Parser) parsePointerType() *ast.StarExpr {
}
-func (P *Parser) tryType() ast.Expr {
+func (P *parser) tryType() ast.Expr {
if P.trace {
defer un(trace(P, "Type (try)"));
}
@@ -752,7 +760,7 @@ func asStmtList(list *vector.Vector) []ast.Stmt {
}
-func (P *Parser) parseStatementList() []ast.Stmt {
+func (P *parser) parseStatementList() []ast.Stmt {
if P.trace {
defer un(trace(P, "StatementList"));
}
@@ -778,7 +786,7 @@ func (P *Parser) parseStatementList() []ast.Stmt {
}
-func (P *Parser) parseBlockStmt() *ast.BlockStmt {
+func (P *parser) parseBlockStmt() *ast.BlockStmt {
if P.trace {
defer un(trace(P, "compositeStmt"));
}
@@ -795,7 +803,7 @@ func (P *Parser) parseBlockStmt() *ast.BlockStmt {
// ----------------------------------------------------------------------------
// Expressions
-func (P *Parser) parseFunctionLit() ast.Expr {
+func (P *parser) parseFunctionLit() ast.Expr {
if P.trace {
defer un(trace(P, "FunctionLit"));
}
@@ -809,7 +817,7 @@ func (P *Parser) parseFunctionLit() ast.Expr {
}
-func (P *Parser) parseStringList(x *ast.StringLit) []*ast.StringLit {
+func (P *parser) parseStringList(x *ast.StringLit) []*ast.StringLit {
if P.trace {
defer un(trace(P, "StringList"));
}
@@ -820,7 +828,7 @@ func (P *Parser) parseStringList(x *ast.StringLit) []*ast.StringLit {
}
for P.tok == token.STRING {
- list.Push(&ast.StringLit{P.pos, P.val});
+ list.Push(&ast.StringLit{P.pos, P.lit});
P.next();
}
@@ -834,7 +842,7 @@ func (P *Parser) parseStringList(x *ast.StringLit) []*ast.StringLit {
}
-func (P *Parser) parseOperand() ast.Expr {
+func (P *parser) parseOperand() ast.Expr {
if P.trace {
defer un(trace(P, "Operand"));
}
@@ -844,22 +852,22 @@ func (P *Parser) parseOperand() ast.Expr {
return P.parseIdent();
case token.INT:
- x := &ast.IntLit{P.pos, P.val};
+ x := &ast.IntLit{P.pos, P.lit};
P.next();
return x;
case token.FLOAT:
- x := &ast.FloatLit{P.pos, P.val};
+ x := &ast.FloatLit{P.pos, P.lit};
P.next();
return x;
case token.CHAR:
- x := &ast.CharLit{P.pos, P.val};
+ x := &ast.CharLit{P.pos, P.lit};
P.next();
return x;
case token.STRING:
- x := &ast.StringLit{P.pos, P.val};
+ x := &ast.StringLit{P.pos, P.lit};
P.next();
if P.tok == token.STRING {
return &ast.StringList{P.parseStringList(x)};
@@ -892,7 +900,7 @@ func (P *Parser) parseOperand() ast.Expr {
}
-func (P *Parser) parseSelectorOrTypeAssertion(x ast.Expr) ast.Expr {
+func (P *parser) parseSelectorOrTypeAssertion(x ast.Expr) ast.Expr {
if P.trace {
defer un(trace(P, "SelectorOrTypeAssertion"));
}
@@ -909,7 +917,7 @@ func (P *Parser) parseSelectorOrTypeAssertion(x ast.Expr) ast.Expr {
var typ ast.Expr;
if P.tok == token.TYPE {
// special case for type switch syntax
- typ = &ast.Ident{P.pos, P.val};
+ typ = &ast.Ident{P.pos, P.lit};
P.next();
} else {
typ = P.parseType();
@@ -923,7 +931,7 @@ func (P *Parser) parseSelectorOrTypeAssertion(x ast.Expr) ast.Expr {
}
-func (P *Parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
+func (P *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
if P.trace {
defer un(trace(P, "IndexOrSlice"));
}
@@ -949,7 +957,7 @@ func (P *Parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
}
-func (P *Parser) parseCall(fun ast.Expr) *ast.CallExpr {
+func (P *parser) parseCall(fun ast.Expr) *ast.CallExpr {
if P.trace {
defer un(trace(P, "Call"));
}
@@ -964,7 +972,7 @@ func (P *Parser) parseCall(fun ast.Expr) *ast.CallExpr {
}
-func (P *Parser) parseElementList() []ast.Expr {
+func (P *parser) parseElementList() []ast.Expr {
if P.trace {
defer un(trace(P, "ElementList"));
}
@@ -975,17 +983,17 @@ func (P *Parser) parseElementList() []ast.Expr {
x := P.parseExpression(0);
if list.Len() == 0 {
// first element determines syntax for remaining elements
- if t, is_binary := x.(*ast.BinaryExpr); is_binary && t.Tok == token.COLON {
+ if t, is_binary := x.(*ast.BinaryExpr); is_binary && t.Op == token.COLON {
singles = false;
}
} else {
// not the first element - check syntax
if singles {
- if t, is_binary := x.(*ast.BinaryExpr); is_binary && t.Tok == token.COLON {
+ if t, is_binary := x.(*ast.BinaryExpr); is_binary && t.Op == token.COLON {
P.error(t.X.Pos(), "single value expected; found pair");
}
} else {
- if t, is_binary := x.(*ast.BinaryExpr); !is_binary || t.Tok != token.COLON {
+ if t, is_binary := x.(*ast.BinaryExpr); !is_binary || t.Op != token.COLON {
P.error(x.Pos(), "key:value pair expected; found single value");
}
}
@@ -1010,7 +1018,7 @@ func (P *Parser) parseElementList() []ast.Expr {
}
-func (P *Parser) parseCompositeLit(typ ast.Expr) ast.Expr {
+func (P *parser) parseCompositeLit(typ ast.Expr) ast.Expr {
if P.trace {
defer un(trace(P, "CompositeLit"));
}
@@ -1025,7 +1033,7 @@ func (P *Parser) parseCompositeLit(typ ast.Expr) ast.Expr {
}
-func (P *Parser) parsePrimaryExpr() ast.Expr {
+func (P *parser) parsePrimaryExpr() ast.Expr {
if P.trace {
defer un(trace(P, "PrimaryExpr"));
}
@@ -1052,7 +1060,7 @@ func (P *Parser) parsePrimaryExpr() ast.Expr {
}
-func (P *Parser) parseUnaryExpr() ast.Expr {
+func (P *parser) parseUnaryExpr() ast.Expr {
if P.trace {
defer un(trace(P, "UnaryExpr"));
}
@@ -1076,7 +1084,7 @@ func (P *Parser) parseUnaryExpr() ast.Expr {
}
-func (P *Parser) parseBinaryExpr(prec1 int) ast.Expr {
+func (P *parser) parseBinaryExpr(prec1 int) ast.Expr {
if P.trace {
defer un(trace(P, "BinaryExpr"));
}
@@ -1095,7 +1103,7 @@ func (P *Parser) parseBinaryExpr(prec1 int) ast.Expr {
}
-func (P *Parser) parseExpression(prec int) ast.Expr {
+func (P *parser) parseExpression(prec int) ast.Expr {
if P.trace {
defer un(trace(P, "Expression"));
}
@@ -1112,7 +1120,7 @@ func (P *Parser) parseExpression(prec int) ast.Expr {
// Statements
-func (P *Parser) parseSimpleStmt() ast.Stmt {
+func (P *parser) parseSimpleStmt() ast.Stmt {
if P.trace {
defer un(trace(P, "SimpleStmt"));
}
@@ -1163,7 +1171,7 @@ func (P *Parser) parseSimpleStmt() ast.Stmt {
}
-func (P *Parser) parseCallExpr() *ast.CallExpr {
+func (P *parser) parseCallExpr() *ast.CallExpr {
x := P.parseExpression(1);
if call, is_call := x.(*ast.CallExpr); is_call {
return call;
@@ -1173,7 +1181,7 @@ func (P *Parser) parseCallExpr() *ast.CallExpr {
}
-func (P *Parser) parseGoStmt() ast.Stmt {
+func (P *parser) parseGoStmt() ast.Stmt {
if P.trace {
defer un(trace(P, "GoStmt"));
}
@@ -1187,7 +1195,7 @@ func (P *Parser) parseGoStmt() ast.Stmt {
}
-func (P *Parser) parseDeferStmt() ast.Stmt {
+func (P *parser) parseDeferStmt() ast.Stmt {
if P.trace {
defer un(trace(P, "DeferStmt"));
}
@@ -1201,7 +1209,7 @@ func (P *Parser) parseDeferStmt() ast.Stmt {
}
-func (P *Parser) parseReturnStmt() *ast.ReturnStmt {
+func (P *parser) parseReturnStmt() *ast.ReturnStmt {
if P.trace {
defer un(trace(P, "ReturnStmt"));
}
@@ -1217,7 +1225,7 @@ func (P *Parser) parseReturnStmt() *ast.ReturnStmt {
}
-func (P *Parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
+func (P *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
if P.trace {
defer un(trace(P, "BranchStmt"));
}
@@ -1232,7 +1240,7 @@ func (P *Parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
}
-func (P *Parser) isExpr(s ast.Stmt) bool {
+func (P *parser) isExpr(s ast.Stmt) bool {
if s == nil {
return true;
}
@@ -1241,7 +1249,7 @@ func (P *Parser) isExpr(s ast.Stmt) bool {
}
-func (P *Parser) asExpr(s ast.Stmt) ast.Expr {
+func (P *parser) asExpr(s ast.Stmt) ast.Expr {
if s == nil {
return nil;
}
@@ -1253,7 +1261,7 @@ func (P *Parser) asExpr(s ast.Stmt) ast.Expr {
}
-func (P *Parser) parseControlClause(isForStmt bool) (s1, s2, s3 ast.Stmt) {
+func (P *parser) parseControlClause(isForStmt bool) (s1, s2, s3 ast.Stmt) {
if P.trace {
defer un(trace(P, "ControlClause"));
}
@@ -1288,7 +1296,7 @@ func (P *Parser) parseControlClause(isForStmt bool) (s1, s2, s3 ast.Stmt) {
}
-func (P *Parser) parseIfStmt() *ast.IfStmt {
+func (P *parser) parseIfStmt() *ast.IfStmt {
if P.trace {
defer un(trace(P, "IfStmt"));
}
@@ -1306,7 +1314,7 @@ func (P *Parser) parseIfStmt() *ast.IfStmt {
}
-func (P *Parser) parseCaseClause() *ast.CaseClause {
+func (P *parser) parseCaseClause() *ast.CaseClause {
if P.trace {
defer un(trace(P, "CaseClause"));
}
@@ -1328,7 +1336,7 @@ func (P *Parser) parseCaseClause() *ast.CaseClause {
}
-func (P *Parser) parseTypeCaseClause() *ast.TypeCaseClause {
+func (P *parser) parseTypeCaseClause() *ast.TypeCaseClause {
if P.trace {
defer un(trace(P, "CaseClause"));
}
@@ -1350,7 +1358,7 @@ func (P *Parser) parseTypeCaseClause() *ast.TypeCaseClause {
}
-func (P *Parser) parseSwitchStmt() ast.Stmt {
+func (P *parser) parseSwitchStmt() ast.Stmt {
if P.trace {
defer un(trace(P, "SwitchStmt"));
}
@@ -1389,7 +1397,7 @@ func (P *Parser) parseSwitchStmt() ast.Stmt {
}
-func (P *Parser) parseCommClause() *ast.CommClause {
+func (P *parser) parseCommClause() *ast.CommClause {
if P.trace {
defer un(trace(P, "CommClause"));
}
@@ -1430,7 +1438,7 @@ func (P *Parser) parseCommClause() *ast.CommClause {
}
-func (P *Parser) parseSelectStmt() *ast.SelectStmt {
+func (P *parser) parseSelectStmt() *ast.SelectStmt {
if P.trace {
defer un(trace(P, "SelectStmt"));
}
@@ -1449,7 +1457,7 @@ func (P *Parser) parseSelectStmt() *ast.SelectStmt {
}
-func (P *Parser) parseForStmt() ast.Stmt {
+func (P *parser) parseForStmt() ast.Stmt {
if P.trace {
defer un(trace(P, "ForStmt"));
}
@@ -1461,7 +1469,7 @@ func (P *Parser) parseForStmt() ast.Stmt {
if as, is_as := s2.(*ast.AssignStmt); is_as {
// possibly a for statement with a range clause; check assignment operator
if as.Tok != token.ASSIGN && as.Tok != token.DEFINE {
- P.error(as.Pos_, "'=' or ':=' expected");
+ P.error(as.TokPos, "'=' or ':=' expected");
return &ast.BadStmt{pos};
}
// check lhs
@@ -1481,9 +1489,9 @@ func (P *Parser) parseForStmt() ast.Stmt {
P.error(as.Rhs[0].Pos(), "expected 1 expressions");
return &ast.BadStmt{pos};
}
- if rhs, is_unary := as.Rhs[0].(*ast.UnaryExpr); is_unary && rhs.Tok == token.RANGE {
+ if rhs, is_unary := as.Rhs[0].(*ast.UnaryExpr); is_unary && rhs.Op == token.RANGE {
// rhs is range expression; check lhs
- return &ast.RangeStmt{pos, key, value, as.Pos_, as.Tok, rhs.X, body}
+ return &ast.RangeStmt{pos, key, value, as.TokPos, as.Tok, rhs.X, body}
} else {
P.error(s2.Pos(), "range clause expected");
return &ast.BadStmt{pos};
@@ -1498,7 +1506,7 @@ func (P *Parser) parseForStmt() ast.Stmt {
}
-func (P *Parser) parseStatement() ast.Stmt {
+func (P *parser) parseStatement() ast.Stmt {
if P.trace {
defer un(trace(P, "Statement"));
}
@@ -1544,7 +1552,7 @@ func (P *Parser) parseStatement() ast.Stmt {
// ----------------------------------------------------------------------------
// Declarations
-func (P *Parser) parseImportSpec(pos Position, doc ast.Comments) *ast.ImportDecl {
+func (P *parser) parseImportSpec(pos token.Position, doc ast.Comments) *ast.ImportDecl {
if P.trace {
defer un(trace(P, "ImportSpec"));
}
@@ -1568,7 +1576,7 @@ func (P *Parser) parseImportSpec(pos Position, doc ast.Comments) *ast.ImportDecl
}
-func (P *Parser) parseConstSpec(pos Position, doc ast.Comments) *ast.ConstDecl {
+func (P *parser) parseConstSpec(pos token.Position, doc ast.Comments) *ast.ConstDecl {
if P.trace {
defer un(trace(P, "ConstSpec"));
}
@@ -1585,7 +1593,7 @@ func (P *Parser) parseConstSpec(pos Position, doc ast.Comments) *ast.ConstDecl {
}
-func (P *Parser) parseTypeSpec(pos Position, doc ast.Comments) *ast.TypeDecl {
+func (P *parser) parseTypeSpec(pos token.Position, doc ast.Comments) *ast.TypeDecl {
if P.trace {
defer un(trace(P, "TypeSpec"));
}
@@ -1597,7 +1605,7 @@ func (P *Parser) parseTypeSpec(pos Position, doc ast.Comments) *ast.TypeDecl {
}
-func (P *Parser) parseVarSpec(pos Position, doc ast.Comments) *ast.VarDecl {
+func (P *parser) parseVarSpec(pos token.Position, doc ast.Comments) *ast.VarDecl {
if P.trace {
defer un(trace(P, "VarSpec"));
}
@@ -1614,7 +1622,7 @@ func (P *Parser) parseVarSpec(pos Position, doc ast.Comments) *ast.VarDecl {
}
-func (P *Parser) parseSpec(pos Position, doc ast.Comments, keyword int) ast.Decl {
+func (P *parser) parseSpec(pos token.Position, doc ast.Comments, keyword int) ast.Decl {
switch keyword {
case token.IMPORT: return P.parseImportSpec(pos, doc);
case token.CONST: return P.parseConstSpec(pos, doc);
@@ -1627,7 +1635,7 @@ func (P *Parser) parseSpec(pos Position, doc ast.Comments, keyword int) ast.Decl
}
-func (P *Parser) parseDecl(keyword int) ast.Decl {
+func (P *parser) parseDecl(keyword int) ast.Decl {
if P.trace {
defer un(trace(P, "Decl"));
}
@@ -1671,7 +1679,7 @@ func (P *Parser) parseDecl(keyword int) ast.Decl {
// func (recv) ident (params) type
// func (recv) ident (params) (results)
-func (P *Parser) parseFunctionDecl() *ast.FuncDecl {
+func (P *parser) parseFunctionDecl() *ast.FuncDecl {
if P.trace {
defer un(trace(P, "FunctionDecl"));
}
@@ -1702,7 +1710,7 @@ func (P *Parser) parseFunctionDecl() *ast.FuncDecl {
}
-func (P *Parser) parseDeclaration() ast.Decl {
+func (P *parser) parseDeclaration() ast.Decl {
if P.trace {
defer un(trace(P, "Declaration"));
}
@@ -1722,23 +1730,18 @@ func (P *Parser) parseDeclaration() ast.Decl {
// ----------------------------------------------------------------------------
-// Program
+// Packages
-// The Parse function is parametrized with one of the following
-// constants. They control how much of the source text is parsed.
-//
+// The Mode constants control how much of the source text is parsed.
+type Mode int;
const (
- ParseEntirePackage = iota;
+ ParseEntirePackage Mode = iota;
ParseImportDeclsOnly;
ParsePackageClauseOnly;
)
-// Parse parses the source...
-//
-// foo bar
-//
-func (P *Parser) Parse(mode int) *ast.Package {
+func (P *parser) parsePackage(mode Mode) *ast.Package {
if P.trace {
defer un(trace(P, "Program"));
}
@@ -1793,3 +1796,33 @@ func (P *Parser) Parse(mode int) *ast.Package {
return &ast.Package{comment, pos, name, decls, comments};
}
+
+
+// ----------------------------------------------------------------------------
+// Parsing of entire programs.
+
+// Parse invokes the Go parser. It calls the scanner's Scan method repeatedly
+// to obtain the token sequence corresponding to the source code. The sequence
+// is parsed according to Go syntax and the corresponding abstract syntax tree
+// is constructed. The error handler err will be used to report syntax errors.
+//
+// If no syntax errors were encountered (i.e., if the error handler was never
+// called), the result is a correct AST. If errors were encountered, the AST
+// may only be constructed partially, with ast.BadX nodes representing the
+// fragments of source code that contained syntax errors.
+//
+// The amount of source text parsed can be controlled with the mode parameter.
+// The flags parameter controls optional parser functionality such as tracing.
+//
+func Parse(scanner Scanner, err ErrorHandler, mode Mode, flags uint) *ast.Package {
+ // initialize parser state
+ var p parser;
+ p.scanner = scanner;
+ p.err = err;
+ p.trace = flags & Trace != 0;
+ p.comments.Init(0);
+ p.next();
+
+ // parse program
+ return p.parsePackage(mode);
+}