mirror of
https://github.com/golang/go
synced 2024-11-22 03:24:41 -07:00
go/parser: report illegal label declarations at ':' rather than guessing the start
Also: - Add parser.SpuriousError flag. If set, the parser reports all (including spurious) errors rather then at most one error per line. - Add -e flag to gofmt and gotype: If set, gofmt and gotype report all (including spurious) errors rather than at most one error per line. - Updated the respective documentation. Fixes #2088. R=rsc CC=golang-dev https://golang.org/cl/4803047
This commit is contained in:
parent
3d552700ce
commit
fa497796f5
@ -14,11 +14,12 @@ Usage:
|
||||
gofmt [flags] [path ...]
|
||||
|
||||
The flags are:
|
||||
|
||||
-d
|
||||
Do not print reformatted sources to standard output.
|
||||
If a file's formatting is different than gofmt's, print diffs
|
||||
to standard output.
|
||||
-e
|
||||
Print all (including spurious) errors.
|
||||
-l
|
||||
Do not print reformatted sources to standard output.
|
||||
If a file's formatting is different from gofmt's, print its name
|
||||
@ -31,6 +32,8 @@ The flags are:
|
||||
Do not print reformatted sources to standard output.
|
||||
If a file's formatting is different from gofmt's, overwrite it
|
||||
with gofmt's version.
|
||||
|
||||
Formatting control flags:
|
||||
-comments=true
|
||||
Print comments; if false, all comments are elided from the output.
|
||||
-spaces
|
||||
@ -40,6 +43,7 @@ The flags are:
|
||||
-tabwidth=8
|
||||
Tab width in spaces.
|
||||
|
||||
|
||||
The rewrite rule specified with the -r flag must be a string of the form:
|
||||
|
||||
pattern -> replacement
|
||||
|
@ -29,6 +29,7 @@ var (
|
||||
rewriteRule = flag.String("r", "", "rewrite rule (e.g., 'α[β:len(α)] -> α[β:]')")
|
||||
simplifyAST = flag.Bool("s", false, "simplify code")
|
||||
doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
|
||||
allErrors = flag.Bool("e", false, "print all (including spurious) errors")
|
||||
|
||||
// layout control
|
||||
comments = flag.Bool("comments", true, "print comments")
|
||||
@ -64,6 +65,9 @@ func initParserMode() {
|
||||
if *comments {
|
||||
parserMode |= parser.ParseComments
|
||||
}
|
||||
if *allErrors {
|
||||
parserMode |= parser.SpuriousErrors
|
||||
}
|
||||
}
|
||||
|
||||
func initPrinterMode() {
|
||||
|
@ -24,18 +24,20 @@ Usage:
|
||||
gotype [flags] [path ...]
|
||||
|
||||
The flags are:
|
||||
-e
|
||||
Print all (including spurious) errors.
|
||||
-p pkgName
|
||||
process only those files in package pkgName.
|
||||
Process only those files in package pkgName.
|
||||
-r
|
||||
recursively process subdirectories.
|
||||
Recursively process subdirectories.
|
||||
-v
|
||||
verbose mode.
|
||||
Verbose mode.
|
||||
|
||||
Debugging flags:
|
||||
-trace
|
||||
print parse trace (disables concurrent parsing).
|
||||
-ast
|
||||
print AST (disables concurrent parsing).
|
||||
Print AST (disables concurrent parsing).
|
||||
-trace
|
||||
Print parse trace (disables concurrent parsing).
|
||||
|
||||
|
||||
Examples
|
||||
|
@ -23,6 +23,7 @@ var (
|
||||
pkgName = flag.String("p", "", "process only those files in package pkgName")
|
||||
recursive = flag.Bool("r", false, "recursively process subdirectories")
|
||||
verbose = flag.Bool("v", false, "verbose mode")
|
||||
allErrors = flag.Bool("e", false, "print all (including spurious) errors")
|
||||
|
||||
// debugging support
|
||||
printTrace = flag.Bool("trace", false, "print parse trace")
|
||||
@ -68,6 +69,9 @@ func parse(fset *token.FileSet, filename string, src []byte) *ast.File {
|
||||
|
||||
// parse entire file
|
||||
mode := parser.DeclarationErrors
|
||||
if *allErrors {
|
||||
mode |= parser.SpuriousErrors
|
||||
}
|
||||
if *printTrace {
|
||||
mode |= parser.Trace
|
||||
}
|
||||
|
@ -48,9 +48,12 @@ func readSource(filename string, src interface{}) ([]byte, os.Error) {
|
||||
return ioutil.ReadFile(filename)
|
||||
}
|
||||
|
||||
func (p *parser) parseEOF() os.Error {
|
||||
p.expect(token.EOF)
|
||||
return p.GetError(scanner.Sorted)
|
||||
func (p *parser) errors() os.Error {
|
||||
mode := scanner.Sorted
|
||||
if p.mode&SpuriousErrors == 0 {
|
||||
mode = scanner.NoMultiples
|
||||
}
|
||||
return p.GetError(mode)
|
||||
}
|
||||
|
||||
// ParseExpr parses a Go expression and returns the corresponding
|
||||
@ -70,7 +73,9 @@ func ParseExpr(fset *token.FileSet, filename string, src interface{}) (ast.Expr,
|
||||
if p.tok == token.SEMICOLON {
|
||||
p.next() // consume automatically inserted semicolon, if any
|
||||
}
|
||||
return x, p.parseEOF()
|
||||
p.expect(token.EOF)
|
||||
|
||||
return x, p.errors()
|
||||
}
|
||||
|
||||
// ParseStmtList parses a list of Go statements and returns the list
|
||||
@ -86,7 +91,10 @@ func ParseStmtList(fset *token.FileSet, filename string, src interface{}) ([]ast
|
||||
|
||||
var p parser
|
||||
p.init(fset, filename, data, 0)
|
||||
return p.parseStmtList(), p.parseEOF()
|
||||
list := p.parseStmtList()
|
||||
p.expect(token.EOF)
|
||||
|
||||
return list, p.errors()
|
||||
}
|
||||
|
||||
// ParseDeclList parses a list of Go declarations and returns the list
|
||||
@ -102,7 +110,10 @@ func ParseDeclList(fset *token.FileSet, filename string, src interface{}) ([]ast
|
||||
|
||||
var p parser
|
||||
p.init(fset, filename, data, 0)
|
||||
return p.parseDeclList(), p.parseEOF()
|
||||
list := p.parseDeclList()
|
||||
p.expect(token.EOF)
|
||||
|
||||
return list, p.errors()
|
||||
}
|
||||
|
||||
// ParseFile parses the source code of a single Go source file and returns
|
||||
@ -133,7 +144,9 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode uint)
|
||||
|
||||
var p parser
|
||||
p.init(fset, filename, data, mode)
|
||||
return p.parseFile(), p.GetError(scanner.NoMultiples) // parseFile() reads to EOF
|
||||
file := p.parseFile() // parseFile reads to EOF
|
||||
|
||||
return file, p.errors()
|
||||
}
|
||||
|
||||
// ParseFiles calls ParseFile for each file in the filenames list and returns
|
||||
|
@ -26,6 +26,7 @@ const (
|
||||
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
|
||||
)
|
||||
|
||||
// The parser structure holds the parser's internal state.
|
||||
@ -1408,7 +1409,13 @@ func (p *parser) parseSimpleStmt(labelOk bool) ast.Stmt {
|
||||
p.declare(stmt, nil, p.labelScope, ast.Lbl, label)
|
||||
return stmt
|
||||
}
|
||||
p.error(x[0].Pos(), "illegal label declaration")
|
||||
// The label declaration typically starts at x[0].Pos(), but the label
|
||||
// declaration may be erroneous due to a token after that position (and
|
||||
// before the ':'). If SpuriousErrors is not set, the (only) error re-
|
||||
// ported for the line is the illegal label error instead of the token
|
||||
// before the ':' that caused the problem. Thus, use the (latest) colon
|
||||
// position for error reporting.
|
||||
p.error(colon, "illegal label declaration")
|
||||
return &ast.BadStmt{x[0].Pos(), colon + 1}
|
||||
|
||||
case token.ARROW:
|
||||
|
Loading…
Reference in New Issue
Block a user