LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package parser implements a parser for Go source files. Input may be | 5 // Package parser implements a parser for Go source files. Input may be |
6 // provided in a variety of forms (see the various Parse* functions); the | 6 // provided in a variety of forms (see the various Parse* functions); the |
7 // output is an abstract syntax tree (AST) representing the Go source. The | 7 // output is an abstract syntax tree (AST) representing the Go source. The |
8 // parser is invoked through one of the Parse* functions. | 8 // parser is invoked through one of the Parse* functions. |
9 // | 9 // |
10 package parser | 10 package parser |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 return &ast.MapType{Map: pos, Key: key, Value: value} | 917 return &ast.MapType{Map: pos, Key: key, Value: value} |
918 } | 918 } |
919 | 919 |
920 func (p *parser) parseChanType() *ast.ChanType { | 920 func (p *parser) parseChanType() *ast.ChanType { |
921 if p.trace { | 921 if p.trace { |
922 defer un(trace(p, "ChanType")) | 922 defer un(trace(p, "ChanType")) |
923 } | 923 } |
924 | 924 |
925 pos := p.pos | 925 pos := p.pos |
926 dir := ast.SEND | ast.RECV | 926 dir := ast.SEND | ast.RECV |
| 927 var arrow token.Pos |
927 if p.tok == token.CHAN { | 928 if p.tok == token.CHAN { |
928 p.next() | 929 p.next() |
929 if p.tok == token.ARROW { | 930 if p.tok == token.ARROW { |
| 931 arrow = p.pos |
930 p.next() | 932 p.next() |
931 dir = ast.SEND | 933 dir = ast.SEND |
932 } | 934 } |
933 } else { | 935 } else { |
934 » » p.expect(token.ARROW) | 936 » » arrow = p.expect(token.ARROW) |
935 p.expect(token.CHAN) | 937 p.expect(token.CHAN) |
936 dir = ast.RECV | 938 dir = ast.RECV |
937 } | 939 } |
938 value := p.parseType() | 940 value := p.parseType() |
939 | 941 |
940 » return &ast.ChanType{Begin: pos, Dir: dir, Value: value} | 942 » return &ast.ChanType{Begin: pos, Arrow: arrow, Dir: dir, Value: value} |
941 } | 943 } |
942 | 944 |
943 // If the result is an identifier, it is not resolved. | 945 // If the result is an identifier, it is not resolved. |
944 func (p *parser) tryIdentOrType(ellipsisOk bool) ast.Expr { | 946 func (p *parser) tryIdentOrType(ellipsisOk bool) ast.Expr { |
945 switch p.tok { | 947 switch p.tok { |
946 case token.IDENT: | 948 case token.IDENT: |
947 return p.parseTypeName() | 949 return p.parseTypeName() |
948 case token.LBRACK: | 950 case token.LBRACK: |
949 return p.parseArrayType(ellipsisOk) | 951 return p.parseArrayType(ellipsisOk) |
950 case token.STRUCT: | 952 case token.STRUCT: |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 | 1392 |
1391 switch p.tok { | 1393 switch p.tok { |
1392 case token.ADD, token.SUB, token.NOT, token.XOR, token.AND: | 1394 case token.ADD, token.SUB, token.NOT, token.XOR, token.AND: |
1393 pos, op := p.pos, p.tok | 1395 pos, op := p.pos, p.tok |
1394 p.next() | 1396 p.next() |
1395 x := p.parseUnaryExpr(false) | 1397 x := p.parseUnaryExpr(false) |
1396 return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)} | 1398 return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)} |
1397 | 1399 |
1398 case token.ARROW: | 1400 case token.ARROW: |
1399 // channel type or receive expression | 1401 // channel type or receive expression |
1400 » » pos := p.pos | 1402 » » arrow := p.pos |
1401 p.next() | 1403 p.next() |
1402 | 1404 |
1403 // If the next token is token.CHAN we still don't know if it | 1405 // If the next token is token.CHAN we still don't know if it |
1404 // is a channel type or a receive operation - we only know | 1406 // is a channel type or a receive operation - we only know |
1405 // once we have found the end of the unary expression. There | 1407 // once we have found the end of the unary expression. There |
1406 // are two cases: | 1408 // are two cases: |
1407 // | 1409 // |
1408 // <- type => (<-type) must be channel type | 1410 // <- type => (<-type) must be channel type |
1409 // <- expr => <-(expr) is a receive from an expression | 1411 // <- expr => <-(expr) is a receive from an expression |
1410 // | 1412 // |
1411 // In the first case, the arrow must be re-associated with | 1413 // In the first case, the arrow must be re-associated with |
1412 // the channel type parsed already: | 1414 // the channel type parsed already: |
1413 // | 1415 // |
1414 // <- (chan type) => (<-chan type) | 1416 // <- (chan type) => (<-chan type) |
1415 // <- (chan<- type) => (<-chan (<-type)) | 1417 // <- (chan<- type) => (<-chan (<-type)) |
1416 | 1418 |
1417 x := p.parseUnaryExpr(false) | 1419 x := p.parseUnaryExpr(false) |
1418 | 1420 |
1419 // determine which case we have | 1421 // determine which case we have |
1420 if typ, ok := x.(*ast.ChanType); ok { | 1422 if typ, ok := x.(*ast.ChanType); ok { |
1421 // (<-type) | 1423 // (<-type) |
1422 | 1424 |
1423 // re-associate position info and <- | 1425 // re-associate position info and <- |
1424 » » » arrow := true | 1426 » » » dir := ast.SEND |
1425 » » » for ok && arrow { | 1427 » » » for ok && dir == ast.SEND { |
1426 » » » » begin := typ.Begin | |
1427 if typ.Dir == ast.RECV { | 1428 if typ.Dir == ast.RECV { |
1428 // error: (<-type) is (<-(<-chan T)) | 1429 // error: (<-type) is (<-(<-chan T)) |
1429 » » » » » p.errorExpected(begin, "'chan'") | 1430 » » » » » p.errorExpected(typ.Arrow, "'chan'") |
1430 } | 1431 } |
1431 » » » » arrow = typ.Dir == ast.SEND | 1432 » » » » arrow, typ.Begin, typ.Arrow = typ.Arrow, arrow,
arrow |
1432 » » » » typ.Begin = pos | 1433 » » » » dir, typ.Dir = typ.Dir, ast.RECV |
1433 » » » » typ.Dir = ast.RECV | |
1434 typ, ok = typ.Value.(*ast.ChanType) | 1434 typ, ok = typ.Value.(*ast.ChanType) |
1435 » » » » // TODO(gri) ast.ChanType should store exact <-
position | 1435 » » » } |
1436 » » » » pos = begin // estimate (we don't have the exact
position of <- for send channels) | 1436 » » » if dir == ast.SEND { |
1437 » » » } | 1437 » » » » p.errorExpected(arrow, "channel type") |
1438 » » » if arrow { | |
1439 » » » » p.errorExpected(pos, "'chan'") | |
1440 } | 1438 } |
1441 | 1439 |
1442 return x | 1440 return x |
1443 } | 1441 } |
1444 | 1442 |
1445 // <-(expr) | 1443 // <-(expr) |
1446 » » return &ast.UnaryExpr{OpPos: pos, Op: token.ARROW, X: p.checkExp
r(x)} | 1444 » » return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: p.checkE
xpr(x)} |
1447 | 1445 |
1448 case token.MUL: | 1446 case token.MUL: |
1449 // pointer type or unary "*" expression | 1447 // pointer type or unary "*" expression |
1450 pos := p.pos | 1448 pos := p.pos |
1451 p.next() | 1449 p.next() |
1452 x := p.parseUnaryExpr(false) | 1450 x := p.parseUnaryExpr(false) |
1453 return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)} | 1451 return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)} |
1454 } | 1452 } |
1455 | 1453 |
1456 return p.parsePrimaryExpr(lhs) | 1454 return p.parsePrimaryExpr(lhs) |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2381 Doc: doc, | 2379 Doc: doc, |
2382 Package: pos, | 2380 Package: pos, |
2383 Name: ident, | 2381 Name: ident, |
2384 Decls: decls, | 2382 Decls: decls, |
2385 Scope: p.pkgScope, | 2383 Scope: p.pkgScope, |
2386 Imports: p.imports, | 2384 Imports: p.imports, |
2387 Unresolved: p.unresolved[0:i], | 2385 Unresolved: p.unresolved[0:i], |
2388 Comments: p.comments, | 2386 Comments: p.comments, |
2389 } | 2387 } |
2390 } | 2388 } |
LEFT | RIGHT |