func (l *Lexer) Err() error {
	return l.r.Err()
}
Err returns the error encountered during lexing, this is often io.EOF but also other errors can be returned.
package formulae  
import (
	"io"
	"strconv"
	"unicode"
	"github.com/tdewolff/formulae/hash"
	"github.com/tdewolff/parse/v2"
	"github.com/tdewolff/parse/v2/buffer"
)
var identifierStart = []*unicode.RangeTable{unicode.Lu, unicode.Ll, unicode.Lt, unicode.Lm, unicode.Lo, unicode.Nl, unicode.Other_ID_Start}
var identifierContinue = []*unicode.RangeTable{unicode.Lu, unicode.Ll, unicode.Lt, unicode.Lm, unicode.Lo, unicode.Nl, unicode.Mn, unicode.Mc, unicode.Nd, unicode.Pc, unicode.Other_ID_Continue}
type Operator int
const (
	UnknownOp Operator = iota
	FuncOp
	OpenOp
	CloseOp
	AddOp
	SubtractOp
	MinusOp
	MultiplyOp
	DivideOp
	PowerOp
)
func (op Operator) String() string {
	switch op {
	case FuncOp:
		return "func"
	case OpenOp:
		return "("
	case CloseOp:
		return ")"
	case AddOp:
		return "+"
	case SubtractOp:
		return "-"
	case MinusOp:
		return "-"
	case MultiplyOp:
		return "*"
	case DivideOp:
		return "/"
	case PowerOp:
		return "^"
	}
	return "Invalid(" + strconv.Itoa(int(op)) + ")"
}
type TokenType uint32
const (
	ErrorToken TokenType = iota  
	UnknownToken
	WhitespaceToken  
	NumericToken
	IdentifierToken
	OperatorToken
)
func (tt TokenType) String() string {
	switch tt {
	case ErrorToken:
		return "Error"
	case UnknownToken:
		return "Unknown"
	case WhitespaceToken:
		return "Whitespace"
	case NumericToken:
		return "Numeric"
	case IdentifierToken:
		return "Identifier"
	case OperatorToken:
		return "Operator"
	}
	return "Invalid(" + strconv.Itoa(int(tt)) + ")"
}
type Lexer struct {
	r        *buffer.Lexer
	lastTT   TokenType
	lastOp   Operator
	lastFunc hash.Hash
}
func NewLexer(r io.Reader) *Lexer {
	return &Lexer{
		r: buffer.NewLexer(r),
	}
}