summaryrefslogtreecommitdiff
path: root/usr/gri
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-02-13 16:27:53 -0800
committerRobert Griesemer <gri@golang.org>2009-02-13 16:27:53 -0800
commit91d9f761da326a8891bdf2ae75da4fe9c71b875d (patch)
treea50c16821ff441581c210fa06f517a761f963a23 /usr/gri
parent086e419da7dce5b64c76b6f3a97ddae705414bd7 (diff)
downloadgolang-91d9f761da326a8891bdf2ae75da4fe9c71b875d.tar.gz
- accept new composite literal syntax
- remove all parsing heuristics - as a result, accept a wider syntax, but parser is simpler R=r OCL=25029 CL=25029
Diffstat (limited to 'usr/gri')
-rw-r--r--usr/gri/pretty/ast.go9
-rw-r--r--usr/gri/pretty/parser.go164
-rw-r--r--usr/gri/pretty/printer.go8
3 files changed, 33 insertions, 148 deletions
diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go
index 05bbafdbf..b82e1f1c5 100644
--- a/usr/gri/pretty/ast.go
+++ b/usr/gri/pretty/ast.go
@@ -167,12 +167,6 @@ type (
Body *Block;
};
- CompositeLit struct {
- Pos_ int; // position of "{"
- Typ *Type;
- Elts Expr;
- };
-
TypeLit struct {
Typ *Type;
};
@@ -208,7 +202,6 @@ type ExprVisitor interface {
DoUnaryExpr(x *UnaryExpr);
DoBasicLit(x *BasicLit);
DoFunctionLit(x *FunctionLit);
- DoCompositeLit(x *CompositeLit);
DoTypeLit(x *TypeLit);
DoSelector(x *Selector);
DoTypeGuard(x *TypeGuard);
@@ -223,7 +216,6 @@ func (x *BinaryExpr) Pos() int { return x.Pos_; }
func (x *UnaryExpr) Pos() int { return x.Pos_; }
func (x *BasicLit) Pos() int { return x.Pos_; }
func (x *FunctionLit) Pos() int { return x.Pos_; }
-func (x *CompositeLit) Pos() int { return x.Pos_; }
func (x *TypeLit) Pos() int { return x.Typ.Pos; }
func (x *Selector) Pos() int { return x.Pos_; }
func (x *TypeGuard) Pos() int { return x.Pos_; }
@@ -237,7 +229,6 @@ func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); }
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); }
-func (x *CompositeLit) Visit(v ExprVisitor) { v.DoCompositeLit(x); }
func (x *TypeLit) Visit(v ExprVisitor) { v.DoTypeLit(x); }
func (x *Selector) Visit(v ExprVisitor) { v.DoSelector(x); }
func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); }
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index 53e409e27..991286733 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -32,7 +32,6 @@ type Parser struct {
opt_semi bool; // true if semicolon is optional
// Nesting levels
- expr_lev int; // 0 = control clause level, 1 = expr inside ()'s
scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc.
// Scopes
@@ -129,7 +128,6 @@ func (P *Parser) Open(trace, sixg, deps bool, scanner *Scanner.Scanner) {
P.comments = vector.New(0);
P.next();
- P.expr_lev = 0;
P.scope_lev = 0;
}
@@ -212,43 +210,6 @@ func (P *Parser) declare(x AST.Expr, kind int, typ *AST.Type) {
// ----------------------------------------------------------------------------
-// AST support
-
-func exprType(x AST.Expr) *AST.Type {
- var typ *AST.Type;
- if t, is_type := x.(*AST.TypeLit); is_type {
- typ = t.Typ
- } else if t, is_ident := x.(*AST.Ident); is_ident {
- // assume a type name
- typ = AST.NewType(t.Pos(), AST.TYPENAME);
- typ.Expr = x;
- } else if t, is_selector := x.(*AST.Selector); is_selector && exprType(t.Sel) != nil {
- // possibly a qualified (type) identifier
- typ = AST.NewType(t.Pos(), AST.TYPENAME);
- typ.Expr = x;
- }
- return typ;
-}
-
-
-func (P *Parser) noType(x AST.Expr) AST.Expr {
- if x != nil {
- lit, ok := x.(*AST.TypeLit);
- if ok {
- P.error(lit.Typ.Pos, "expected expression, found type");
- x = &AST.BasicLit(lit.Typ.Pos, Scanner.STRING, "");
- }
- }
- return x;
-}
-
-
-func (P *Parser) newBinaryExpr(pos, tok int, x, y AST.Expr) *AST.BinaryExpr {
- return &AST.BinaryExpr(pos, tok, P.noType(x), P.noType(y));
-}
-
-
-// ----------------------------------------------------------------------------
// Common productions
func (P *Parser) tryType() *AST.Type;
@@ -295,10 +256,10 @@ func (P *Parser) parseIdentList() AST.Expr {
P.next();
y := P.parseIdent(nil);
if last == nil {
- last = P.newBinaryExpr(pos, Scanner.COMMA, x, y);
+ last = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
x = last;
} else {
- last.Y = P.newBinaryExpr(pos, Scanner.COMMA, last.Y, y);
+ last.Y = &AST.BinaryExpr(pos, Scanner.COMMA, last.Y, y);
last = last.Y.(*AST.BinaryExpr);
}
}
@@ -371,7 +332,7 @@ func (P *Parser) parseArrayType() *AST.Type {
t := AST.NewType(P.pos, AST.ARRAY);
P.expect(Scanner.LBRACK);
if P.tok == Scanner.ELLIPSIS {
- t.Expr = P.newBinaryExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
+ t.Expr = &AST.BinaryExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
P.next();
} else if P.tok != Scanner.RBRACK {
t.Expr = P.parseExpression(1);
@@ -708,19 +669,19 @@ func (P *Parser) tryType() *AST.Type {
defer un(trace(P, "Type (try)"));
}
- t := AST.BadType;
switch P.tok {
- case Scanner.IDENT: t = P.parseTypeName();
- case Scanner.LBRACK: t = P.parseArrayType();
- case Scanner.CHAN, Scanner.ARROW: t = P.parseChannelType();
- case Scanner.INTERFACE: t = P.parseInterfaceType();
- case Scanner.FUNC: t = P.parseFunctionType();
- case Scanner.MAP: t = P.parseMapType();
- case Scanner.STRUCT: t = P.parseStructType();
- case Scanner.MUL: t = P.parsePointerType();
- default: t = nil; // no type found
- }
- return t;
+ case Scanner.IDENT: return P.parseTypeName();
+ case Scanner.LBRACK: return P.parseArrayType();
+ case Scanner.CHAN, Scanner.ARROW: return P.parseChannelType();
+ case Scanner.INTERFACE: return P.parseInterfaceType();
+ case Scanner.FUNC: return P.parseFunctionType();
+ case Scanner.MAP: return P.parseMapType();
+ case Scanner.STRUCT: return P.parseStructType();
+ case Scanner.MUL: return P.parsePointerType();
+ }
+
+ // no type found
+ return nil;
}
@@ -801,10 +762,10 @@ func (P *Parser) parseExpressionList() AST.Expr {
P.next();
y := P.parseExpression(1);
if first {
- x = P.newBinaryExpr(pos, Scanner.COMMA, x, y);
+ x = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
first = false;
} else {
- x.(*AST.BinaryExpr).Y = P.newBinaryExpr(pos, Scanner.COMMA, x.(*AST.BinaryExpr).Y, y);
+ x.(*AST.BinaryExpr).Y = &AST.BinaryExpr(pos, Scanner.COMMA, x.(*AST.BinaryExpr).Y, y);
}
}
@@ -820,11 +781,9 @@ func (P *Parser) parseFunctionLit() AST.Expr {
pos := P.pos;
P.expect(Scanner.FUNC);
typ := P.parseSignature();
- P.expr_lev++;
P.scope_lev++;
body := P.parseBlock(typ, Scanner.LBRACE);
P.scope_lev--;
- P.expr_lev--;
return &AST.FunctionLit(pos, typ, body);
}
@@ -841,9 +800,7 @@ func (P *Parser) parseOperand() AST.Expr {
case Scanner.LPAREN:
P.next();
- P.expr_lev++;
x := P.parseExpression(1);
- P.expr_lev--;
P.expect(Scanner.RPAREN);
return x;
@@ -904,9 +861,7 @@ func (P *Parser) parseIndex(x AST.Expr) AST.Expr {
pos := P.pos;
P.expect(Scanner.LBRACK);
- P.expr_lev++;
i := P.parseExpression(0);
- P.expr_lev--;
P.expect(Scanner.RBRACK);
return &AST.Index(pos, x, i);
@@ -915,43 +870,6 @@ func (P *Parser) parseIndex(x AST.Expr) AST.Expr {
func (P *Parser) parseBinaryExpr(prec1 int) AST.Expr
-func (P *Parser) parseCall(f AST.Expr) AST.Expr {
- if P.trace {
- defer un(trace(P, "Call"));
- }
-
- call := &AST.Call(P.pos, f, nil);
- P.expect(Scanner.LPAREN);
- if P.tok != Scanner.RPAREN {
- P.expr_lev++;
- var t *AST.Type;
- if x0, ok := f.(*AST.Ident); ok && (x0.Obj.Ident == "new" || x0.Obj.Ident == "make") {
- // heuristic: assume it's a new(T) or make(T, ...) call, try to parse a type
- t = P.tryType();
- }
- if t != nil {
- // we found a type
- args := &AST.TypeLit(t);
- if P.tok == Scanner.COMMA {
- pos := P.pos;
- P.next();
- y := P.parseExpressionList();
- // create list manually because NewExpr checks for type expressions
- args := &AST.BinaryExpr(pos, Scanner.COMMA, args, y);
- }
- call.Args = args;
- } else {
- // normal argument list
- call.Args = P.parseExpressionList();
- }
- P.expr_lev--;
- }
- P.expect(Scanner.RPAREN);
-
- return call;
-}
-
-
func (P *Parser) parseCompositeElements() AST.Expr {
x := P.parseExpression(0);
if P.tok == Scanner.COMMA {
@@ -965,7 +883,7 @@ func (P *Parser) parseCompositeElements() AST.Expr {
}
var last *AST.BinaryExpr;
- for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
+ for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
y := P.parseExpression(0);
if singles {
@@ -979,10 +897,10 @@ func (P *Parser) parseCompositeElements() AST.Expr {
}
if last == nil {
- last = P.newBinaryExpr(pos, Scanner.COMMA, x, y);
+ last = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
x = last;
} else {
- last.Y = P.newBinaryExpr(pos, Scanner.COMMA, last.Y, y);
+ last.Y = &AST.BinaryExpr(pos, Scanner.COMMA, last.Y, y);
last = last.Y.(*AST.BinaryExpr);
}
@@ -999,20 +917,20 @@ func (P *Parser) parseCompositeElements() AST.Expr {
}
-func (P *Parser) parseCompositeLit(t *AST.Type) AST.Expr {
+func (P *Parser) parseCallOrCompositeLit(f AST.Expr) AST.Expr {
if P.trace {
- defer un(trace(P, "CompositeLit"));
+ defer un(trace(P, "CallOrCompositeLit"));
}
pos := P.pos;
- P.expect(Scanner.LBRACE);
- var elts AST.Expr;
- if P.tok != Scanner.RBRACE {
- elts = P.parseCompositeElements();
+ P.expect(Scanner.LPAREN);
+ var args AST.Expr;
+ if P.tok != Scanner.RPAREN {
+ args = P.parseCompositeElements();
}
- P.expect(Scanner.RBRACE);
+ P.expect(Scanner.RPAREN);
- return &AST.CompositeLit(pos, t, elts);
+ return &AST.Call(pos, f, args);
}
@@ -1026,20 +944,7 @@ func (P *Parser) parsePrimaryExpr() AST.Expr {
switch P.tok {
case Scanner.PERIOD: x = P.parseSelectorOrTypeGuard(x);
case Scanner.LBRACK: x = P.parseIndex(x);
- case Scanner.LPAREN: x = P.parseCall(x);
- case Scanner.LBRACE:
- // assume a composite literal only if x could be a type
- // and if we are not inside a control clause (expr_lev >= 0)
- // (composites inside control clauses must be parenthesized)
- var t *AST.Type;
- if P.expr_lev >= 0 {
- t = exprType(x);
- }
- if t != nil {
- x = P.parseCompositeLit(t);
- } else {
- return x;
- }
+ case Scanner.LPAREN: x = P.parseCallOrCompositeLit(x);
default:
return x;
}
@@ -1085,7 +990,7 @@ func (P *Parser) parseBinaryExpr(prec1 int) AST.Expr {
pos, tok := P.pos, P.tok;
P.next();
y := P.parseBinaryExpr(prec + 1);
- x = P.newBinaryExpr(pos, tok, x, y);
+ x = &AST.BinaryExpr(pos, tok, x, y);
}
}
@@ -1102,7 +1007,7 @@ func (P *Parser) parseExpression(prec int) AST.Expr {
panic("precedence must be >= 0");
}
- return P.noType(P.parseBinaryExpr(prec));
+ return P.parseBinaryExpr(prec);
}
@@ -1153,7 +1058,7 @@ func (P *Parser) parseSimpleStat(range_ok bool) AST.Stat {
}
}
// TODO changed ILLEGAL -> NONE
- return &AST.ExpressionStat(x.Pos(), Scanner.ILLEGAL, P.newBinaryExpr(pos, tok, x, y));
+ return &AST.ExpressionStat(x.Pos(), Scanner.ILLEGAL, &AST.BinaryExpr(pos, tok, x, y));
default:
if AST.ExprLen(x) != 1 {
@@ -1223,8 +1128,6 @@ func (P *Parser) parseControlClause(isForStat bool) (init AST.Stat, expr AST.Exp
}
if P.tok != Scanner.LBRACE {
- prev_lev := P.expr_lev;
- P.expr_lev = -1;
if P.tok != Scanner.SEMICOLON {
init = P.parseSimpleStat(isForStat);
// TODO check for range clause and exit if found
@@ -1249,7 +1152,6 @@ func (P *Parser) parseControlClause(isForStat bool) (init AST.Stat, expr AST.Exp
}
}
}
- P.expr_lev = prev_lev;
}
return init, expr, post;
@@ -1361,7 +1263,7 @@ func (P *Parser) parseCommClause() *AST.CaseClause {
P.next();
if P.tok == Scanner.ARROW {
y := P.parseExpression(1);
- x = P.newBinaryExpr(pos, tok, x, y);
+ x = &AST.BinaryExpr(pos, tok, x, y);
} else {
P.expect(Scanner.ARROW); // use expect() error handling
}
diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go
index 67a961580..64ce715a1 100644
--- a/usr/gri/pretty/printer.go
+++ b/usr/gri/pretty/printer.go
@@ -680,14 +680,6 @@ func (P *Printer) DoFunctionLit(x *AST.FunctionLit) {
}
-func (P *Printer) DoCompositeLit(x *AST.CompositeLit) {
- P.Type(x.Typ);
- P.String(x.Pos(), "{");
- P.Expr(x.Elts);
- P.String(0, "}");
-}
-
-
func (P *Printer) DoSelector(x *AST.Selector) {
P.Expr1(x.X, Scanner.HighestPrec);
P.String(x.Pos(), ".");