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
}
func (p *parser) parseLhsList() []ast.Expr {
+ old := p.inRhs
+ p.inRhs = false
list := p.parseExprList(true)
switch p.tok {
case token.DEFINE:
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
}
// ----------------------------------------------------------------------------
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 {
}
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
}
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
}
// ----------------------------------------------------------------------------
`package p; func f() { _ = (<-<- /* ERROR "expected 'chan'" */ chan int)(nil) };`,
`package p; func f() { _ = (<-chan<-chan<-chan<-chan<-chan<- /* ERROR "expected channel type" */ int)(nil) };`,
`package p; func f() { var t []int; t /* ERROR "expected identifier on left side of :=" */ [0] := 0 };`,
+ `package p; func f() { if x := g(); x = /* ERROR "expected '=='" */ 0 {}};`,
+ `package p; func f() { _ = x = /* ERROR "expected '=='" */ 0 {}};`,
+ `package p; func f() { _ = 1 == func()int { var x bool; x = x = /* ERROR "expected '=='" */ true; return x }() };`,
}
func TestInvalid(t *testing.T) {