func (p *Parser) Exp(t *token.Token) (ast.ExpNode, *token.Token) {
	var exp ast.ExpNode
	exp, t = p.ShortExp(t)
	var op ops.Op
	var stack []item
	last := item{exp, op}
	for t.Type.IsBinOp() {
		op = binopMap[t.Type]
		exp, t = p.ShortExp(p.Scan())
		for len(stack) > 0 {
			pdiff := op.Precedence() - last.op.Precedence()
			if pdiff > 0 || (pdiff == 0 && op == ops.OpConcat) {
				break
			}
			stack, last = mergepop(stack, last)
		}
		stack = append(stack, last)
		last = item{exp, op}
	}
	for len(stack) > 0 {
		stack, last = mergepop(stack, last)
	}
	return last.exp, t
}
Exp parses any expression.
package parsing
import (
	"errors"
	"fmt"
	"github.com/arnodel/golua/ops"
	"github.com/arnodel/golua/token"
	"github.com/arnodel/golua/ast"
)
type Parser struct {
	getToken func() *token.Token
}
type Error struct {
	Got      *token.Token
	Expected string
}
func (e Error) Error() string {
	expected := e.Expected
	if expected == "" {
		expected = "unexpected symbol"
	} else {
		expected = "expected " + expected
	}
	var tok string
	if e.Got.Type == token.EOF {
		tok = "<eof>"
	} else {
		tok = "'" + string(e.Got.Lit) + "'"
	}
	return fmt.Sprintf("%d:%d: %s near %s", e.Got.Line, e.Got.Column, expected, tok)
}
func ParseExp(getToken func() *token.Token) (exp ast.ExpNode, err error) {
	defer func() {
		if r := recover(); r != nil {
			exp = nil
			var ok bool
			err, ok = r.(error)
			if !ok {
				err = errors.New("Unknown error")
			}
		}
	}()
	parser := &Parser{getToken}
	var t *token.Token
	exp, t = parser.Exp(getToken())
	expectType(t, token.EOF, "<eof>")
	return
}
func ParseChunk(getToken func() *token.Token) (stat ast.BlockStat, err error) {
	defer func() {
		if r := recover(); r != nil {
			stat = ast.BlockStat{}
			var ok bool
			err, ok = r.(error)
			if !ok {
				err = errors.New("Unknown error")
			}
		}
	}()
	parser := &Parser{getToken}
	var t *token.Token
	stat, t = parser.Block(getToken())
	expectType(t, token.EOF, "<eof>")
	return
}
func (p *Parser) Scan() *token.Token {
	return p.getToken()
}
func (p *Parser) Stat(t *token.Token) (ast.Stat, *token.Token) {
	switch t.Type {
	case token.SgSemicolon:
		return ast.NewEmptyStat(t), p.Scan()
	case token.KwBreak:
		return ast.NewBreakStat(t), p.Scan()
	case token.KwGoto:
		dest := p.Scan()
		expectIdent(dest)
		return ast.NewGotoStat(t, ast.NewName(dest)), p.Scan()
	case token.KwDo:
		stat, closer := p.Block(p.Scan())
		expectType(closer, token.KwEnd, "'end'")
		return stat, p.Scan()
	case token.KwWhile:
		cond, doTok := p.Exp(p.Scan())
		expectType(doTok, token.KwDo, "'do'")
		body, endTok := p.Block(p.Scan())
		expectType(endTok, token.KwEnd, "'end'")
		return ast.NewWhileStat(t, endTok, cond, body), p.Scan()
	case token.KwRepeat:
		body, untilTok := p.Block(p.Scan())
		expectType(untilTok, token.KwUntil, "'until'")
		cond, next := p.Exp(p.Scan())
		return ast.NewRepeatStat(t, body, cond), next
	case token.KwIf:
		return p.If(t)
	case token.KwFor:
		return p.For(t)
	case token.KwFunction:
		return p.FunctionStat(t)
	case token.KwLocal:
		return p.Local(t)
	case token.SgDoubleColon:
		name, t := p.Name(p.Scan())
		expectType(t, token.SgDoubleColon, "'::'")
		return ast.NewLabelStat(name), p.Scan()
	default:
		var exp ast.ExpNode
		exp, t = p.PrefixExp(t)
		switch e := exp.(type) {
		case ast.Stat:
			return e, t
		case ast.Var:
			vars := []ast.Var{e}
			var pexp ast.ExpNode
			for t.Type == token.SgComma {
				pexp, t = p.PrefixExp(p.Scan())
				if v, ok := pexp.(ast.Var); ok {
					vars = append(vars, v)
				} else {
					tokenError(t, "expected variable")
				}
			}
			expectType(t, token.SgAssign, "'='")
			exps, t := p.ExpList(p.Scan())
			return ast.NewAssignStat(vars, exps), t
		default:
			tokenError(t, "")
		}
	}
	return nil, nil
}
func (p *Parser) If(t *token.Token) (ast.IfStat, *token.Token) {
	cond, thenTok := p.Exp(p.Scan())
	expectType(thenTok, token.KwThen, "'then'")
	thenBlock, endTok := p.Block(p.Scan())
	ifStat := ast.NewIfStat(t, cond, thenBlock)
	for {
		switch endTok.Type {
		case token.KwElseIf:
			cond, thenTok = p.Exp(p.Scan())
			expectType(thenTok, token.KwThen, "'then'")
			thenBlock, endTok = p.Block(p.Scan())
			ifStat = ifStat.AddElseIf(cond, thenBlock)
		case token.KwEnd:
			return ifStat, p.Scan()
		case token.KwElse:
			elseBlock, elseTok := p.Block(p.Scan())
			expectType(elseTok, token.KwEnd, "'end'")
			ifStat = ifStat.WithElse(endTok, elseBlock)
			return ifStat, p.Scan()
		default:
			tokenError(t, "'elseif' or 'end' or 'else'")
		}
	}
}
func (p *Parser) For(t *token.Token) (ast.Stat, *token.Token) {
	name, nextTok := p.Name(p.Scan())
	if nextTok.Type == token.SgAssign {
		params := make([]ast.ExpNode, 3)
		params[0], nextTok = p.Exp(p.Scan())
		expectType(nextTok, token.SgComma, "','")
		params[1], nextTok = p.Exp(p.Scan())
		if nextTok.Type == token.SgComma {
			params[2], nextTok = p.Exp(p.Scan())
		} else {
			params[2] = ast.NewInt(1)
		}
		expectType(nextTok, token.KwDo, "'do'")
		body, endTok := p.Block(p.Scan())
		expectType(endTok, token.KwEnd, "'end'")
		forStat := ast.NewForStat(t, endTok, name, params, body)
		return forStat, p.Scan()
	}
	names := []ast.Name{name}
	for nextTok.Type == token.SgComma {
		name, nextTok = p.Name(p.Scan())
		names = append(names, name)
	}
	expected := "'in'"
	if len(names) == 1 {
		expected = "'=' or 'in'"
	}
	expectType(nextTok, token.KwIn, expected)
	exp, nextTok := p.Exp(p.Scan())
	params := []ast.ExpNode{exp}
	for nextTok.Type == token.SgComma {
		exp, nextTok = p.Exp(p.Scan())
		params = append(params, exp)
	}
	expectType(nextTok, token.KwDo, "'do'")
	body, endTok := p.Block(p.Scan())
	expectType(endTok, token.KwEnd, "'end'")
	forInStat := ast.NewForInStat(t, endTok, names, params, body)
	return forInStat, p.Scan()
}
func (p *Parser) Local(t *token.Token) (ast.Stat, *token.Token) {
	t = p.Scan()
	if t.Type == token.KwFunction {
		name, t := p.Name(p.Scan())
		fx, t := p.FunctionDef(t)
		return ast.NewLocalFunctionStat(name, fx), t
	}
	name, t := p.Name(t)
	names := []ast.Name{name}
	for t.Type == token.SgComma {
		name, t = p.Name(p.Scan())
		names = append(names, name)
	}
	var values []ast.ExpNode
	if t.Type == token.SgAssign {
		values, t = p.ExpList(p.Scan())
	}
	return ast.NewLocalStat(names, values), t
}
func (p *Parser) FunctionStat(t *token.Token) (ast.Stat, *token.Token) {
	name, t := p.Name(p.Scan())
	var v ast.Var = name
	var method ast.Name
	for t.Type == token.SgDot {
		name, t = p.Name(p.Scan())
		v = ast.NewIndexExp(v, name.AstString())
	}
	if t.Type == token.SgColon {
		method, t = p.Name(p.Scan())
	}
	fx, t := p.FunctionDef(t)
	return ast.NewFunctionStat(v, method, fx), t
}
func (p *Parser) Block(t *token.Token) (ast.BlockStat, *token.Token) {
	var stats []ast.Stat
	var next ast.Stat
	for {
		switch t.Type {
		case token.KwReturn:
			ret, t := p.Return(t)
			return ast.NewBlockStat(stats, ret), t
		case token.KwEnd, token.KwElse, token.KwElseIf, token.KwUntil, token.EOF:
			return ast.NewBlockStat(stats, nil), t
		default:
			next, t = p.Stat(t)
			stats = append(stats, next)
		}
	}
}
func (p *Parser) Return(t *token.Token) ([]ast.ExpNode, *token.Token) {
	t = p.Scan()
	switch t.Type {
	case token.SgSemicolon:
		return []ast.ExpNode{}, p.Scan()
	case token.KwEnd, token.KwElse, token.KwElseIf, token.KwUntil, token.EOF:
		return []ast.ExpNode{}, t
	default:
		exps, t := p.ExpList(t)
		if t.Type == token.SgSemicolon {
			t = p.Scan()
		}
		return exps, t
	}
}
type item struct {
	exp ast.ExpNode
	op  ops.Op
}
func mergepop(stack []item, it item) ([]item, item) {
	i := len(stack) - 1
	top := stack[i]
	top.exp = ast.NewBinOp(top.exp, it.op, it.exp)
	return stack[:i], top
}