// parseOperand may return an expression or a raw type (incl. array // types of the form [...]T. Callers must verify the result. // If lhs is set and the result is an identifier, it is not resolved. // func (p *parser) parseOperand(lhs bool) ast.Expr { switch p.tok { case token.IDENT: x := p.parseIdent() // if !lhs { // p.resolve(x) // } return x case token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING: x := &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit} p.next() return x case token.LPAREN: lparen := p.pos p.next() p.exprLev++ x := p.parseOperand(false) p.exprLev-- rparen := p.expect(token.RPAREN) return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen} default: p.errorExpected(p.pos, "operand") return &ast.BadExpr{From: p.pos - 10, To: p.pos + 10} } }
func (p *parser) expect(tok token.Token) token.Pos { pos := p.pos if p.tok != tok { p.errorExpected(pos, "'"+tok.String()+"'") } p.next() // make progress return pos }
func (p *parser) init(fset *token.FileSet, filename string, src []byte) { p.file = fset.AddFile(filename, -1, len(src)) var m scanner.Mode eh := func(pos token.Position, msg string) { p.errors.Add(pos, msg) } p.scanner.Init(p.file, src, eh, m) p.next() }
func (p *parser) parseIdent() *ast.Ident { pos := p.pos name := "_" if p.tok == token.IDENT { name = p.lit p.next() } else { p.expect(token.IDENT) // use expect() error handling } return &ast.Ident{NamePos: pos, Name: name} }