// var-ident [ "[" [ int ] "]" ] [ type-ident ] = var-init func (p *Parser) parseVarSpec() *ast.Var { p.push("var-spec") defer p.pop() ret := new(ast.Var) err := func() *ast.Var { p.skipUntil(tt.Semi) return ret } if !p.expect(tt.Ident) { return err() } t := p.last() ret.Name = t.Lit ret.NameToken = t if p.ahead(tt.Lbrack) || p.ahead(tt.Ident) { if !p.parseVarType(ret) { return err() } } if p.accept(tt.Assign) { if !p.parseVarValue(ret) { return err() } } if !p.expect(tt.Semi) { return err() } return ret }
func (p *Parser) parseVarType(v *ast.Var) bool { p.push("var-type") defer p.pop() if p.accept(tt.Lbrack) { v.IsArray = true if p.accept(tt.Int) { v.SizeToken = p.last() } if !p.expect(tt.Rbrack) { return false } } if p.accept(tt.Ident) { t := p.last() v.TypeToken = t v.Type = t.Lit } else if v.IsArray { return false } return true }
func (p *Parser) parseVarValue(v *ast.Var) bool { if p.accept(tt.Lbrace) { p.extend("var-init-array") defer p.pop() for { if p.accept(tt.Rbrace) { break } if p.accept(tt.Int) || p.accept(tt.Char) || p.accept(tt.Float) { v.InitValues = append(v.InitValues, p.last()) } else { p.expecting("init values") return false } if p.accept(tt.Comma) { continue } if !p.ahead(tt.Rbrace) { p.expecting("comma or right brace") return false } } } else if p.accept(tt.String) { p.extend("var-init-string") defer p.pop() v.InitValue = p.last() } else if p.accept(tt.Int) || p.accept(tt.Char) || p.accept(tt.Float) { p.extend("var-init-single") defer p.pop() v.InitValue = p.last() } else { p.expecting("init var value") return false } return true }