Commit 18ed7e69 authored by Robert Griesemer's avatar Robert Griesemer

- 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
parent 070738c3
......@@ -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); }
......
......@@ -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;
}
......@@ -211,43 +209,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
......@@ -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
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();
}
return t;
// 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
}
......
......@@ -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(), ".");
......
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