1
0
mirror of https://github.com/golang/go synced 2024-11-26 00:17:58 -07:00

- 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
This commit is contained in:
Robert Griesemer 2009-02-13 16:27:53 -08:00
parent 070738c30c
commit 18ed7e690a
3 changed files with 32 additions and 147 deletions

View File

@ -167,12 +167,6 @@ type (
Body *Block; Body *Block;
}; };
CompositeLit struct {
Pos_ int; // position of "{"
Typ *Type;
Elts Expr;
};
TypeLit struct { TypeLit struct {
Typ *Type; Typ *Type;
}; };
@ -208,7 +202,6 @@ type ExprVisitor interface {
DoUnaryExpr(x *UnaryExpr); DoUnaryExpr(x *UnaryExpr);
DoBasicLit(x *BasicLit); DoBasicLit(x *BasicLit);
DoFunctionLit(x *FunctionLit); DoFunctionLit(x *FunctionLit);
DoCompositeLit(x *CompositeLit);
DoTypeLit(x *TypeLit); DoTypeLit(x *TypeLit);
DoSelector(x *Selector); DoSelector(x *Selector);
DoTypeGuard(x *TypeGuard); 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 *UnaryExpr) Pos() int { return x.Pos_; }
func (x *BasicLit) Pos() int { return x.Pos_; } func (x *BasicLit) Pos() int { return x.Pos_; }
func (x *FunctionLit) 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 *TypeLit) Pos() int { return x.Typ.Pos; }
func (x *Selector) Pos() int { return x.Pos_; } func (x *Selector) Pos() int { return x.Pos_; }
func (x *TypeGuard) 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 *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); } func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); }
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(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 *TypeLit) Visit(v ExprVisitor) { v.DoTypeLit(x); }
func (x *Selector) Visit(v ExprVisitor) { v.DoSelector(x); } func (x *Selector) Visit(v ExprVisitor) { v.DoSelector(x); }
func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); } func (x *TypeGuard) Visit(v ExprVisitor) { v.DoTypeGuard(x); }

View File

@ -32,7 +32,6 @@ type Parser struct {
opt_semi bool; // true if semicolon is optional opt_semi bool; // true if semicolon is optional
// Nesting levels // 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. scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc.
// Scopes // Scopes
@ -129,7 +128,6 @@ func (P *Parser) Open(trace, sixg, deps bool, scanner *Scanner.Scanner) {
P.comments = vector.New(0); P.comments = vector.New(0);
P.next(); P.next();
P.expr_lev = 0;
P.scope_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 // Common productions
@ -295,10 +256,10 @@ func (P *Parser) parseIdentList() AST.Expr {
P.next(); P.next();
y := P.parseIdent(nil); y := P.parseIdent(nil);
if last == nil { if last == nil {
last = P.newBinaryExpr(pos, Scanner.COMMA, x, y); last = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
x = last; x = last;
} else { } 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); last = last.Y.(*AST.BinaryExpr);
} }
} }
@ -371,7 +332,7 @@ func (P *Parser) parseArrayType() *AST.Type {
t := AST.NewType(P.pos, AST.ARRAY); t := AST.NewType(P.pos, AST.ARRAY);
P.expect(Scanner.LBRACK); P.expect(Scanner.LBRACK);
if P.tok == Scanner.ELLIPSIS { 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(); P.next();
} else if P.tok != Scanner.RBRACK { } else if P.tok != Scanner.RBRACK {
t.Expr = P.parseExpression(1); t.Expr = P.parseExpression(1);
@ -708,19 +669,19 @@ func (P *Parser) tryType() *AST.Type {
defer un(trace(P, "Type (try)")); defer un(trace(P, "Type (try)"));
} }
t := AST.BadType;
switch P.tok { switch P.tok {
case Scanner.IDENT: t = P.parseTypeName(); case Scanner.IDENT: return P.parseTypeName();
case Scanner.LBRACK: t = P.parseArrayType(); case Scanner.LBRACK: return P.parseArrayType();
case Scanner.CHAN, Scanner.ARROW: t = P.parseChannelType(); case Scanner.CHAN, Scanner.ARROW: return P.parseChannelType();
case Scanner.INTERFACE: t = P.parseInterfaceType(); case Scanner.INTERFACE: return P.parseInterfaceType();
case Scanner.FUNC: t = P.parseFunctionType(); case Scanner.FUNC: return P.parseFunctionType();
case Scanner.MAP: t = P.parseMapType(); case Scanner.MAP: return P.parseMapType();
case Scanner.STRUCT: t = P.parseStructType(); case Scanner.STRUCT: return P.parseStructType();
case Scanner.MUL: t = P.parsePointerType(); case Scanner.MUL: return P.parsePointerType();
default: t = nil; // no type found
} }
return t;
// no type found
return nil;
} }
@ -801,10 +762,10 @@ func (P *Parser) parseExpressionList() AST.Expr {
P.next(); P.next();
y := P.parseExpression(1); y := P.parseExpression(1);
if first { if first {
x = P.newBinaryExpr(pos, Scanner.COMMA, x, y); x = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
first = false; first = false;
} else { } 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; pos := P.pos;
P.expect(Scanner.FUNC); P.expect(Scanner.FUNC);
typ := P.parseSignature(); typ := P.parseSignature();
P.expr_lev++;
P.scope_lev++; P.scope_lev++;
body := P.parseBlock(typ, Scanner.LBRACE); body := P.parseBlock(typ, Scanner.LBRACE);
P.scope_lev--; P.scope_lev--;
P.expr_lev--;
return &AST.FunctionLit(pos, typ, body); return &AST.FunctionLit(pos, typ, body);
} }
@ -841,9 +800,7 @@ func (P *Parser) parseOperand() AST.Expr {
case Scanner.LPAREN: case Scanner.LPAREN:
P.next(); P.next();
P.expr_lev++;
x := P.parseExpression(1); x := P.parseExpression(1);
P.expr_lev--;
P.expect(Scanner.RPAREN); P.expect(Scanner.RPAREN);
return x; return x;
@ -904,9 +861,7 @@ func (P *Parser) parseIndex(x AST.Expr) AST.Expr {
pos := P.pos; pos := P.pos;
P.expect(Scanner.LBRACK); P.expect(Scanner.LBRACK);
P.expr_lev++;
i := P.parseExpression(0); i := P.parseExpression(0);
P.expr_lev--;
P.expect(Scanner.RBRACK); P.expect(Scanner.RBRACK);
return &AST.Index(pos, x, i); 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) 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 { func (P *Parser) parseCompositeElements() AST.Expr {
x := P.parseExpression(0); x := P.parseExpression(0);
if P.tok == Scanner.COMMA { if P.tok == Scanner.COMMA {
@ -965,7 +883,7 @@ func (P *Parser) parseCompositeElements() AST.Expr {
} }
var last *AST.BinaryExpr; 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); y := P.parseExpression(0);
if singles { if singles {
@ -979,10 +897,10 @@ func (P *Parser) parseCompositeElements() AST.Expr {
} }
if last == nil { if last == nil {
last = P.newBinaryExpr(pos, Scanner.COMMA, x, y); last = &AST.BinaryExpr(pos, Scanner.COMMA, x, y);
x = last; x = last;
} else { } 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); 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 { if P.trace {
defer un(trace(P, "CompositeLit")); defer un(trace(P, "CallOrCompositeLit"));
} }
pos := P.pos; pos := P.pos;
P.expect(Scanner.LBRACE); P.expect(Scanner.LPAREN);
var elts AST.Expr; var args AST.Expr;
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RPAREN {
elts = P.parseCompositeElements(); 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 { switch P.tok {
case Scanner.PERIOD: x = P.parseSelectorOrTypeGuard(x); case Scanner.PERIOD: x = P.parseSelectorOrTypeGuard(x);
case Scanner.LBRACK: x = P.parseIndex(x); case Scanner.LBRACK: x = P.parseIndex(x);
case Scanner.LPAREN: x = P.parseCall(x); case Scanner.LPAREN: x = P.parseCallOrCompositeLit(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;
}
default: default:
return x; return x;
} }
@ -1085,7 +990,7 @@ func (P *Parser) parseBinaryExpr(prec1 int) AST.Expr {
pos, tok := P.pos, P.tok; pos, tok := P.pos, P.tok;
P.next(); P.next();
y := P.parseBinaryExpr(prec + 1); 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"); 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 // 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: default:
if AST.ExprLen(x) != 1 { 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 { if P.tok != Scanner.LBRACE {
prev_lev := P.expr_lev;
P.expr_lev = -1;
if P.tok != Scanner.SEMICOLON { if P.tok != Scanner.SEMICOLON {
init = P.parseSimpleStat(isForStat); init = P.parseSimpleStat(isForStat);
// TODO check for range clause and exit if found // 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; return init, expr, post;
@ -1361,7 +1263,7 @@ func (P *Parser) parseCommClause() *AST.CaseClause {
P.next(); P.next();
if P.tok == Scanner.ARROW { if P.tok == Scanner.ARROW {
y := P.parseExpression(1); y := P.parseExpression(1);
x = P.newBinaryExpr(pos, tok, x, y); x = &AST.BinaryExpr(pos, tok, x, y);
} else { } else {
P.expect(Scanner.ARROW); // use expect() error handling P.expect(Scanner.ARROW); // use expect() error handling
} }

View File

@ -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) { func (P *Printer) DoSelector(x *AST.Selector) {
P.Expr1(x.X, Scanner.HighestPrec); P.Expr1(x.X, Scanner.HighestPrec);
P.String(x.Pos(), "."); P.String(x.Pos(), ".");