OLD | NEW |
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 // A parser for Go source files. Input may be provided in a variety of | 5 // A parser for Go source files. Input may be provided in a variety of |
6 // forms (see the various Parse* functions); the output is an abstract | 6 // forms (see the various Parse* functions); the output is an abstract |
7 // syntax tree (AST) representing the Go source. The parser is invoked | 7 // syntax tree (AST) representing the Go source. The parser is invoked |
8 // through one of the Parse* functions. | 8 // through one of the Parse* functions. |
9 // | 9 // |
10 package parser | 10 package parser |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 if p.tok != token.COMMA { | 519 if p.tok != token.COMMA { |
520 break | 520 break |
521 } | 521 } |
522 p.next() | 522 p.next() |
523 } | 523 } |
524 | 524 |
525 // if we had a list of identifiers, it must be followed by a type | 525 // if we had a list of identifiers, it must be followed by a type |
526 typ := p.tryType() | 526 typ := p.tryType() |
527 | 527 |
528 // optional tag | 528 // optional tag |
529 » var tag []*ast.BasicLit | 529 » var tag *ast.BasicLit |
530 if p.tok == token.STRING { | 530 if p.tok == token.STRING { |
531 » » x := &ast.BasicLit{p.pos, p.tok, p.lit} | 531 » » tag = &ast.BasicLit{p.pos, p.tok, p.lit} |
532 p.next() | 532 p.next() |
533 tag = []*ast.BasicLit{x} | |
534 } | 533 } |
535 | 534 |
536 // analyze case | 535 // analyze case |
537 var idents []*ast.Ident | 536 var idents []*ast.Ident |
538 if typ != nil { | 537 if typ != nil { |
539 // IdentifierList Type | 538 // IdentifierList Type |
540 idents = p.makeIdentList(&list) | 539 idents = p.makeIdentList(&list) |
541 } else { | 540 } else { |
542 // Type (anonymous field) | 541 // Type (anonymous field) |
543 if len(list) == 1 { | 542 if len(list) == 1 { |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 // restricting what they are supposed to accept depending | 1121 // restricting what they are supposed to accept depending |
1123 // on context. | 1122 // on context. |
1124 | 1123 |
1125 // checkExpr checks that x is an expression (and not a type). | 1124 // checkExpr checks that x is an expression (and not a type). |
1126 func (p *parser) checkExpr(x ast.Expr) ast.Expr { | 1125 func (p *parser) checkExpr(x ast.Expr) ast.Expr { |
1127 // TODO(gri): should provide predicate in AST nodes | 1126 // TODO(gri): should provide predicate in AST nodes |
1128 switch t := x.(type) { | 1127 switch t := x.(type) { |
1129 case *ast.BadExpr: | 1128 case *ast.BadExpr: |
1130 case *ast.Ident: | 1129 case *ast.Ident: |
1131 case *ast.BasicLit: | 1130 case *ast.BasicLit: |
1132 case *ast.StringList: | |
1133 case *ast.FuncLit: | 1131 case *ast.FuncLit: |
1134 case *ast.CompositeLit: | 1132 case *ast.CompositeLit: |
1135 case *ast.ParenExpr: | 1133 case *ast.ParenExpr: |
1136 case *ast.SelectorExpr: | 1134 case *ast.SelectorExpr: |
1137 case *ast.IndexExpr: | 1135 case *ast.IndexExpr: |
1138 case *ast.SliceExpr: | 1136 case *ast.SliceExpr: |
1139 case *ast.TypeAssertExpr: | 1137 case *ast.TypeAssertExpr: |
1140 if t.Type == nil { | 1138 if t.Type == nil { |
1141 // the form X.(type) is only allowed in type switch expr
essions | 1139 // the form X.(type) is only allowed in type switch expr
essions |
1142 p.errorExpected(x.Pos(), "expression") | 1140 p.errorExpected(x.Pos(), "expression") |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1820 ident = &ast.Ident{p.pos, ast.NewObj(ast.Pkg, p.pos, ".")} | 1818 ident = &ast.Ident{p.pos, ast.NewObj(ast.Pkg, p.pos, ".")} |
1821 p.next() | 1819 p.next() |
1822 } else if p.tok == token.IDENT { | 1820 } else if p.tok == token.IDENT { |
1823 ident = p.parseIdent(ast.Pkg) | 1821 ident = p.parseIdent(ast.Pkg) |
1824 // TODO(gri) Make sure the ident is not already declared in the | 1822 // TODO(gri) Make sure the ident is not already declared in the |
1825 // package scope. Also, cannot add the same name to | 1823 // package scope. Also, cannot add the same name to |
1826 // the package scope later. | 1824 // the package scope later. |
1827 p.declIdent(p.fileScope, ident) | 1825 p.declIdent(p.fileScope, ident) |
1828 } | 1826 } |
1829 | 1827 |
1830 » var path []*ast.BasicLit | 1828 » var path *ast.BasicLit |
1831 if p.tok == token.STRING { | 1829 if p.tok == token.STRING { |
1832 » » x := &ast.BasicLit{p.pos, p.tok, p.lit} | 1830 » » path = &ast.BasicLit{p.pos, p.tok, p.lit} |
1833 p.next() | 1831 p.next() |
1834 path = []*ast.BasicLit{x} | |
1835 } else { | 1832 } else { |
1836 p.expect(token.STRING) // use expect() error handling | 1833 p.expect(token.STRING) // use expect() error handling |
1837 } | 1834 } |
1838 p.expectSemi() | 1835 p.expectSemi() |
1839 | 1836 |
1840 return &ast.ImportSpec{doc, ident, path, p.lineComment} | 1837 return &ast.ImportSpec{doc, ident, path, p.lineComment} |
1841 } | 1838 } |
1842 | 1839 |
1843 | 1840 |
1844 func parseConstSpec(p *parser, doc *ast.CommentGroup) ast.Spec { | 1841 func parseConstSpec(p *parser, doc *ast.CommentGroup) ast.Spec { |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2093 | 2090 |
2094 // convert declaration list | 2091 // convert declaration list |
2095 decls = make([]ast.Decl, len(list)) | 2092 decls = make([]ast.Decl, len(list)) |
2096 for i, x := range list { | 2093 for i, x := range list { |
2097 decls[i] = x.(ast.Decl) | 2094 decls[i] = x.(ast.Decl) |
2098 } | 2095 } |
2099 } | 2096 } |
2100 | 2097 |
2101 return &ast.File{doc, pos, ident, decls, p.comments} | 2098 return &ast.File{doc, pos, ident, decls, p.comments} |
2102 } | 2099 } |
OLD | NEW |