summaryrefslogtreecommitdiff
path: root/src/pkg/go/parser/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/go/parser/parser.go')
-rw-r--r--src/pkg/go/parser/parser.go55
1 files changed, 41 insertions, 14 deletions
diff --git a/src/pkg/go/parser/parser.go b/src/pkg/go/parser/parser.go
index a021a5abe..f4a690a6f 100644
--- a/src/pkg/go/parser/parser.go
+++ b/src/pkg/go/parser/parser.go
@@ -48,7 +48,8 @@ type parser struct {
syncCnt int // number of calls to syncXXX without progress
// Non-syntactic parser control
- exprLev int // < 0: in control clause, >= 0: in expression
+ exprLev int // < 0: in control clause, >= 0: in expression
+ inRhs bool // if set, the parser is parsing a rhs expression
// Ordinary identifier scopes
pkgScope *ast.Scope // pkgScope.Outer == nil
@@ -539,6 +540,8 @@ func (p *parser) parseExprList(lhs bool) (list []ast.Expr) {
}
func (p *parser) parseLhsList() []ast.Expr {
+ old := p.inRhs
+ p.inRhs = false
list := p.parseExprList(true)
switch p.tok {
case token.DEFINE:
@@ -560,11 +563,16 @@ func (p *parser) parseLhsList() []ast.Expr {
p.resolve(x)
}
}
+ p.inRhs = old
return list
}
func (p *parser) parseRhsList() []ast.Expr {
- return p.parseExprList(false)
+ old := p.inRhs
+ p.inRhs = true
+ list := p.parseExprList(false)
+ p.inRhs = old
+ return list
}
// ----------------------------------------------------------------------------
@@ -1505,6 +1513,14 @@ func (p *parser) parseUnaryExpr(lhs bool) ast.Expr {
return p.parsePrimaryExpr(lhs)
}
+func (p *parser) tokPrec() (token.Token, int) {
+ tok := p.tok
+ if p.inRhs && tok == token.ASSIGN {
+ tok = token.EQL
+ }
+ return tok, tok.Precedence()
+}
+
// If lhs is set and the result is an identifier, it is not resolved.
func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr {
if p.trace {
@@ -1512,10 +1528,13 @@ func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr {
}
x := p.parseUnaryExpr(lhs)
- for prec := p.tok.Precedence(); prec >= prec1; prec-- {
- for p.tok.Precedence() == prec {
- pos, op := p.pos, p.tok
- p.next()
+ for _, prec := p.tokPrec(); prec >= prec1; prec-- {
+ for {
+ op, oprec := p.tokPrec()
+ if oprec != prec {
+ break
+ }
+ pos := p.expect(op)
if lhs {
p.resolve(x)
lhs = false
@@ -1541,11 +1560,19 @@ func (p *parser) parseExpr(lhs bool) ast.Expr {
}
func (p *parser) parseRhs() ast.Expr {
- return p.checkExpr(p.parseExpr(false))
+ old := p.inRhs
+ p.inRhs = true
+ x := p.checkExpr(p.parseExpr(false))
+ p.inRhs = old
+ return x
}
func (p *parser) parseRhsOrType() ast.Expr {
- return p.checkExprOrType(p.parseExpr(false))
+ old := p.inRhs
+ p.inRhs = true
+ x := p.checkExprOrType(p.parseExpr(false))
+ p.inRhs = old
+ return x
}
// ----------------------------------------------------------------------------
@@ -2091,7 +2118,7 @@ func (p *parser) parseStmt() (s ast.Stmt) {
// ----------------------------------------------------------------------------
// Declarations
-type parseSpecFunction func(p *parser, doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec
+type parseSpecFunction func(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec
func isValidImport(lit string) bool {
const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
@@ -2210,12 +2237,12 @@ func (p *parser) parseGenDecl(keyword token.Token, f parseSpecFunction) *ast.Gen
lparen = p.pos
p.next()
for iota := 0; p.tok != token.RPAREN && p.tok != token.EOF; iota++ {
- list = append(list, f(p, p.leadComment, keyword, iota))
+ list = append(list, f(p.leadComment, keyword, iota))
}
rparen = p.expect(token.RPAREN)
p.expectSemi()
} else {
- list = append(list, f(p, nil, keyword, 0))
+ list = append(list, f(nil, keyword, 0))
}
return &ast.GenDecl{
@@ -2316,10 +2343,10 @@ func (p *parser) parseDecl(sync func(*parser)) ast.Decl {
var f parseSpecFunction
switch p.tok {
case token.CONST, token.VAR:
- f = (*parser).parseValueSpec
+ f = p.parseValueSpec
case token.TYPE:
- f = (*parser).parseTypeSpec
+ f = p.parseTypeSpec
case token.FUNC:
return p.parseFuncDecl()
@@ -2371,7 +2398,7 @@ func (p *parser) parseFile() *ast.File {
if p.mode&PackageClauseOnly == 0 {
// import decls
for p.tok == token.IMPORT {
- decls = append(decls, p.parseGenDecl(token.IMPORT, (*parser).parseImportSpec))
+ decls = append(decls, p.parseGenDecl(token.IMPORT, p.parseImportSpec))
}
if p.mode&ImportsOnly == 0 {