LEFT | RIGHT |
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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 // Usage pattern: defer closeScope(openScope(p)); | 276 // Usage pattern: defer closeScope(openScope(p)); |
277 func openScope(p *parser) *parser { | 277 func openScope(p *parser) *parser { |
278 p.topScope = ast.NewScope(p.topScope) | 278 p.topScope = ast.NewScope(p.topScope) |
279 return p | 279 return p |
280 } | 280 } |
281 | 281 |
282 | 282 |
283 func closeScope(p *parser) { p.topScope = p.topScope.Outer } | 283 func closeScope(p *parser) { p.topScope = p.topScope.Outer } |
284 | 284 |
285 | 285 |
286 func (p *parser) parseIdent(kind ast.Kind) *ast.Ident { | 286 func (p *parser) parseIdent(kind ast.ObjKind) *ast.Ident { |
287 obj := ast.NewObj(ast.Err, p.pos, "") | 287 obj := ast.NewObj(ast.Err, p.pos, "") |
288 if p.tok == token.IDENT { | 288 if p.tok == token.IDENT { |
289 obj.Name = string(p.lit) | 289 obj.Name = string(p.lit) |
290 p.next() | 290 p.next() |
291 } else { | 291 } else { |
292 p.expect(token.IDENT) // use expect() error handling | 292 p.expect(token.IDENT) // use expect() error handling |
293 } | 293 } |
294 return &ast.Ident{obj.Pos, obj} | 294 return &ast.Ident{obj.Pos, obj} |
295 } | 295 } |
296 | 296 |
297 | 297 |
298 func (p *parser) declIdent(kind ast.Kind) *ast.Ident { | 298 // TODO(gri) Separate parsing from declaration since an identifier's |
| 299 // scope often starts only after the type has been seen. |
| 300 func (p *parser) declIdent(kind ast.ObjKind) *ast.Ident { |
299 obj := ast.NewObj(kind, p.pos, "") | 301 obj := ast.NewObj(kind, p.pos, "") |
300 if p.tok == token.IDENT { | 302 if p.tok == token.IDENT { |
301 obj.Name = string(p.lit) | 303 obj.Name = string(p.lit) |
302 // TODO(gri) Consider reversing the conditionals below: | 304 // TODO(gri) Consider reversing the conditionals below: |
303 // always do the declaration but only report | 305 // always do the declaration but only report |
304 // error if enabled (may be necessary to get | 306 // error if enabled (may be necessary to get |
305 // search functionality in the presence of | 307 // search functionality in the presence of |
306 // incorrect files). | 308 // incorrect files). |
307 if p.check && !p.topScope.Declare(obj) { | 309 if p.check && !p.topScope.Declare(obj) { |
308 // TODO(gri) Declare could return already-declared | 310 // TODO(gri) Declare could return already-declared |
309 » » » // object very good error message. | 311 » » » // object for a very good error message. |
310 p.Error(obj.Pos, "'"+obj.Name+"' declared already") | 312 p.Error(obj.Pos, "'"+obj.Name+"' declared already") |
311 } | 313 } |
312 p.next() | 314 p.next() |
313 } else { | 315 } else { |
314 p.expect(token.IDENT) // use expect() error handling | 316 p.expect(token.IDENT) // use expect() error handling |
315 } | 317 } |
316 return &ast.Ident{obj.Pos, obj} | 318 return &ast.Ident{obj.Pos, obj} |
317 } | 319 } |
318 | 320 |
319 | 321 |
320 func (p *parser) declIdentList(kind ast.Kind) []*ast.Ident { | 322 // TODO(gri) Separate parsing from declaration since an identifier's |
| 323 // scope often starts only after the type has been seen. |
| 324 func (p *parser) declIdentList(kind ast.ObjKind) []*ast.Ident { |
321 if p.trace { | 325 if p.trace { |
322 defer un(trace(p, "IdentList")) | 326 defer un(trace(p, "IdentList")) |
323 } | 327 } |
324 | 328 |
325 var list vector.Vector | 329 var list vector.Vector |
326 list.Push(p.declIdent(kind)) | 330 list.Push(p.declIdent(kind)) |
327 for p.tok == token.COMMA { | 331 for p.tok == token.COMMA { |
328 p.next() | 332 p.next() |
329 list.Push(p.declIdent(kind)) | 333 list.Push(p.declIdent(kind)) |
330 } | 334 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 } | 454 } |
451 | 455 |
452 | 456 |
453 func (p *parser) makeIdentList(list *vector.Vector) []*ast.Ident { | 457 func (p *parser) makeIdentList(list *vector.Vector) []*ast.Ident { |
454 idents := make([]*ast.Ident, len(*list)) | 458 idents := make([]*ast.Ident, len(*list)) |
455 for i, x := range *list { | 459 for i, x := range *list { |
456 ident, isIdent := x.(*ast.Ident) | 460 ident, isIdent := x.(*ast.Ident) |
457 if !isIdent { | 461 if !isIdent { |
458 pos := x.(ast.Expr).Pos() | 462 pos := x.(ast.Expr).Pos() |
459 p.errorExpected(pos, "identifier") | 463 p.errorExpected(pos, "identifier") |
460 » » » idents[i] = &ast.Ident{pos, &ast.Object{Pos: pos}} | 464 » » » idents[i] = &ast.Ident{pos, ast.NewObj(ast.Err, pos, "")
} |
461 } | 465 } |
462 idents[i] = ident | 466 idents[i] = ident |
463 } | 467 } |
464 return idents | 468 return idents |
465 } | 469 } |
466 | 470 |
467 | 471 |
468 func (p *parser) parseFieldDecl() *ast.Field { | 472 func (p *parser) parseFieldDecl() *ast.Field { |
469 if p.trace { | 473 if p.trace { |
470 defer un(trace(p, "FieldDecl")) | 474 defer un(trace(p, "FieldDecl")) |
(...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1943 // Source files | 1947 // Source files |
1944 | 1948 |
1945 func (p *parser) parseFile() *ast.File { | 1949 func (p *parser) parseFile() *ast.File { |
1946 if p.trace { | 1950 if p.trace { |
1947 defer un(trace(p, "File")) | 1951 defer un(trace(p, "File")) |
1948 } | 1952 } |
1949 | 1953 |
1950 // package clause | 1954 // package clause |
1951 doc := p.leadComment | 1955 doc := p.leadComment |
1952 pos := p.expect(token.PACKAGE) | 1956 pos := p.expect(token.PACKAGE) |
1953 » ident := p.parseIdent(ast.Pkg) // package name is in no scope | 1957 » ident := p.parseIdent(ast.Pkg) // package name is in no scope |
1954 p.expectSemi() | 1958 p.expectSemi() |
1955 | 1959 |
1956 // file block | 1960 // file block |
1957 defer closeScope(openScope(p)) | 1961 defer closeScope(openScope(p)) |
1958 | 1962 |
1959 var decls []ast.Decl | 1963 var decls []ast.Decl |
1960 | 1964 |
1961 // Don't bother parsing the rest if we had errors already. | 1965 // Don't bother parsing the rest if we had errors already. |
1962 // Likely not a Go source file at all. | 1966 // Likely not a Go source file at all. |
1963 | 1967 |
(...skipping 13 matching lines...) Expand all Loading... |
1977 | 1981 |
1978 // convert declaration list | 1982 // convert declaration list |
1979 decls = make([]ast.Decl, len(list)) | 1983 decls = make([]ast.Decl, len(list)) |
1980 for i, x := range list { | 1984 for i, x := range list { |
1981 decls[i] = x.(ast.Decl) | 1985 decls[i] = x.(ast.Decl) |
1982 } | 1986 } |
1983 } | 1987 } |
1984 | 1988 |
1985 return &ast.File{doc, pos, ident, decls, p.comments} | 1989 return &ast.File{doc, pos, ident, decls, p.comments} |
1986 } | 1990 } |
LEFT | RIGHT |