return nil
}
- // { ImportDecl ";" }
- for p.got(_Import) {
- f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
- p.want(_Semi)
- }
-
- // { TopLevelDecl ";" }
+ // Accept import declarations anywhere for error tolerance, but complain.
+ // { ( ImportDecl | TopLevelDecl ) ";" }
+ prev := _Import
for p.tok != _EOF {
+ if p.tok == _Import && prev != _Import {
+ p.syntaxError("imports must appear before other declarations")
+ }
+ prev = p.tok
+
switch p.tok {
+ case _Import:
+ p.next()
+ f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
+
case _Const:
p.next()
f.DeclList = p.appendGroup(f.DeclList, p.constDecl)
} else {
p.syntaxError("non-declaration statement outside function body")
}
- p.advance(_Const, _Type, _Var, _Func)
+ p.advance(_Import, _Const, _Type, _Var, _Func)
continue
}
if p.tok != _EOF && !p.got(_Semi) {
p.syntaxError("after top level declaration")
- p.advance(_Const, _Type, _Var, _Func)
+ p.advance(_Import, _Const, _Type, _Var, _Func)
}
}
// p.tok == _EOF
return d
}
if !d.Path.Bad && d.Path.Kind != StringLit {
- p.syntaxError("import path must be a string")
+ p.syntaxErrorAt(d.Path.Pos(), "import path must be a string")
d.Path.Bad = true
}
// d.Path.Bad || d.Path.Kind == StringLit
import ; // ERROR missing import path
import
var /* ERROR missing import path */ _ int
-import .; // ERROR missing import path
+import .; // ERROR missing import path
+import 'x' // ERROR import path must be a string
+var _ int
+import /* ERROR imports must appear before other declarations */ _ "math"
+// Don't repeat previous error for each immediately following import ...
import ()
import (.) // ERROR missing import path
import (
.
) // ERROR missing import path
-var _ = fmt.Println // avoid imported but not used error
+// ... but remind with error again if we start a new import section after
+// other declarations
+var _ = fmt.Println
+import /* ERROR imports must appear before other declarations */ _ "math"
+import _ "math"