diff options
Diffstat (limited to 'gcc-4.8/libgo/go/go/parser/interface.go')
-rw-r--r-- | gcc-4.8/libgo/go/go/parser/interface.go | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/gcc-4.8/libgo/go/go/parser/interface.go b/gcc-4.8/libgo/go/go/parser/interface.go index fac513e55..149257ca6 100644 --- a/gcc-4.8/libgo/go/go/parser/interface.go +++ b/gcc-4.8/libgo/go/go/parser/interface.go @@ -52,12 +52,13 @@ func readSource(filename string, src interface{}) ([]byte, error) { type Mode uint const ( - PackageClauseOnly Mode = 1 << iota // parsing stops after package clause - ImportsOnly // parsing stops after import declarations - ParseComments // parse comments and add them to AST - Trace // print a trace of parsed productions - DeclarationErrors // report declaration errors - SpuriousErrors // report all (not just the first) errors per line + PackageClauseOnly Mode = 1 << iota // stop parsing after package clause + ImportsOnly // stop parsing after import declarations + ParseComments // parse comments and add them to AST + Trace // print a trace of parsed productions + DeclarationErrors // report declaration errors + SpuriousErrors // same as AllErrors, for backward-compatibility + AllErrors = SpuriousErrors // report all errors (not just the first 10 on different lines) ) // ParseFile parses the source code of a single Go source file and returns @@ -79,35 +80,39 @@ const ( // representing the fragments of erroneous source code). Multiple errors // are returned via a scanner.ErrorList which is sorted by file position. // -func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (*ast.File, error) { +func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (f *ast.File, err error) { // get source text, err := readSource(filename, src) if err != nil { return nil, err } - // parse source var p parser - p.init(fset, filename, text, mode) - f := p.parseFile() - if f == nil { - // source is not a valid Go source file - satisfy - // ParseFile API and return a valid (but) empty - // *ast.File - f = &ast.File{ - Name: new(ast.Ident), - Scope: ast.NewScope(nil), + defer func() { + if e := recover(); e != nil { + _ = e.(bailout) // re-panics if it's not a bailout + } + + // set result values + if f == nil { + // source is not a valid Go source file - satisfy + // ParseFile API and return a valid (but) empty + // *ast.File + f = &ast.File{ + Name: new(ast.Ident), + Scope: ast.NewScope(nil), + } } - } - // sort errors - if p.mode&SpuriousErrors == 0 { - p.errors.RemoveMultiples() - } else { p.errors.Sort() - } + err = p.errors.Err() + }() + + // parse source + p.init(fset, filename, text, mode) + f = p.parseFile() - return f, p.errors.Err() + return } // ParseDir calls ParseFile for the files in the directory specified by path and @@ -157,16 +162,27 @@ func ParseDir(fset *token.FileSet, path string, filter func(os.FileInfo) bool, m } // ParseExpr is a convenience function for obtaining the AST of an expression x. -// The position information recorded in the AST is undefined. +// The position information recorded in the AST is undefined. The filename used +// in error messages is the empty string. // func ParseExpr(x string) (ast.Expr, error) { - // parse x within the context of a complete package for correct scopes; - // use //line directive for correct positions in error messages and put - // x alone on a separate line (handles line comments), followed by a ';' - // to force an error if the expression is incomplete - file, err := ParseFile(token.NewFileSet(), "", "package p;func _(){_=\n//line :1\n"+x+"\n;}", 0) - if err != nil { - return nil, err + var p parser + p.init(token.NewFileSet(), "", []byte(x), 0) + + // Set up pkg-level scopes to avoid nil-pointer errors. + // This is not needed for a correct expression x as the + // parser will be ok with a nil topScope, but be cautious + // in case of an erroneous x. + p.openScope() + p.pkgScope = p.topScope + e := p.parseRhsOrType() + p.closeScope() + assert(p.topScope == nil, "unbalanced scopes") + + if p.errors.Len() > 0 { + p.errors.Sort() + return nil, p.errors.Err() } - return file.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.AssignStmt).Rhs[0], nil + + return e, nil } |