func lex(input string, capacity int) (*lexer, <-chan Token) {
	l := &lexer{
		input:  input,
		tokens: make(chan Token, capacity),
	}
	go l.run()  
	return l, l.tokens
}
lex creates a new lexer for the given input
package lexer
import (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"
)
type TokenType int
const (
	ItemError TokenType = iota
	ItemEOF
	ItemQuery
	ItemInsert
	ItemDelete
	ItemCreate
	ItemConstruct
	ItemDeconstruct
	ItemDrop
	ItemGraph
	ItemData
	ItemInto
	ItemFrom
	ItemWhere
	ItemAs
	ItemType
	ItemID
	ItemAt
	ItemIn
	ItemBefore
	ItemAfter
	ItemBetween
	ItemCount
	ItemDistinct
	ItemSum
	ItemGroup
	ItemBy
	ItemOrder
	ItemHaving
	ItemAsc
	ItemDesc
	ItemLimit
	ItemBinding
	ItemNode
	ItemBlankNode
	ItemLiteral
	ItemPredicate
	ItemPredicateBound
	ItemTime
	ItemLBracket
	ItemRBracket
	ItemLPar
	ItemRPar
	ItemDot
	ItemSemicolon
	ItemComma
	ItemLT
	ItemGT
	ItemEQ
	ItemNot
	ItemAnd
	ItemOr
	ItemShow
	ItemGraphs
	ItemOptional
	ItemFilter
	ItemFilterFunction
)
func (tt TokenType) String() string {
	switch tt {
	case ItemError:
		return "ERROR"
	case ItemEOF:
		return "EOF"
	case ItemQuery:
		return "QUERY"
	case ItemInsert:
		return "INSERT"
	case ItemDelete:
		return "DELETE"
	case ItemCreate:
		return "CREATE"
	case ItemConstruct:
		return "CONSTRUCT"
	case ItemDeconstruct:
		return "DECONSTRUCT"
	case ItemDrop:
		return "DROP"
	case ItemGraph:
		return "Graph"
	case ItemData:
		return "DATA"
	case ItemInto:
		return "INTO"
	case ItemFrom:
		return "FROM"
	case ItemWhere:
		return "WHERE"
	case ItemCount:
		return "COUNT"
	case ItemSum:
		return "SUM"
	case ItemGroup:
		return "GROUP"
	case ItemBy:
		return "BY"
	case ItemHaving:
		return "HAVING"
	case ItemOrder:
		return "ORDER"
	case ItemAsc:
		return "ASC"
	case ItemDesc:
		return "DESC"
	case ItemLimit:
		return "LIMIT"
	case ItemAs:
		return "AS"
	case ItemBefore:
		return "BEFORE"
	case ItemAfter:
		return "AFTER"
	case ItemBetween:
		return "BETWEEN"
	case ItemBinding:
		return "BINDING"
	case ItemNode:
		return "NODE"
	case ItemBlankNode:
		return "BLANK_NODE"
	case ItemLiteral:
		return "LITERAL"
	case ItemPredicate:
		return "PREDICATE"
	case ItemPredicateBound:
		return "PREDICATE_BOUND"
	case ItemTime:
		return "TIME"
	case ItemLBracket:
		return "LEFT_BRACKET"
	case ItemRBracket:
		return "RIGHT_BRACKET"
	case ItemLPar:
		return "LEFT_PARENT"
	case ItemRPar:
		return "RIGHT_PARENT"
	case ItemDot:
		return "DOT"
	case ItemSemicolon:
		return "SEMICOLON"
	case ItemComma:
		return "COMMA"
	case ItemLT:
		return "LT"
	case ItemGT:
		return "GT"
	case ItemEQ:
		return "EQ"
	case ItemNot:
		return "NOT"
	case ItemAnd:
		return "AND"
	case ItemOr:
		return "OR"
	case ItemID:
		return "ID"
	case ItemType:
		return "TYPE"
	case ItemAt:
		return "AT"
	case ItemIn:
		return "IN"
	case ItemDistinct:
		return "DISTINCT"
	case ItemShow:
		return "SHOW"
	case ItemGraphs:
		return "GRAPHS"
	case ItemOptional:
		return "OPTIONAL"
	case ItemFilter:
		return "FILTER"
	case ItemFilterFunction:
		return "FILTER_FUNCTION"
	default:
		return "UNKNOWN"
	}
}
const (
	eof            = rune(-1)
	binding        = rune('?')
	leftBracket    = rune('{')
	rightBracket   = rune('}')
	leftPar        = rune('(')
	rightPar       = rune(')')
	rightSquarePar = rune(']')
	dot            = rune('.')
	colon          = rune(':')
	semicolon      = rune(';')
	comma          = rune(',')
	slash          = rune('/')
	underscore     = rune('_')
	backSlash      = rune('\\')
	lt             = rune('<')
	gt             = rune('>')
	eq             = rune('=')
	quote          = rune('"')
	hat            = rune('^')
	at             = rune('@')
	newLine        = rune('\n')
	query          = "select"
	insert         = "insert"
	delete         = "delete"
	create         = "create"
	construct      = "construct"
	deconstruct    = "deconstruct"
	drop           = "drop"
	graph          = "graph"
	data           = "data"
	into           = "into"
	from           = "from"
	where          = "where"
	optional       = "optional"
	filter         = "filter"
	as             = "as"
	before         = "before"
	after          = "after"
	between        = "between"
	count          = "count"
	distinct       = "distinct"
	sum            = "sum"
	group          = "group"
	having         = "having"
	by             = "by"
	order          = "order"
	asc            = "asc"
	desc           = "desc"
	limit          = "limit"
	not            = "not"
	and            = "and"
	or             = "or"
	id             = "id"
	typeKeyword    = "type"
	atKeyword      = "at"
	inKeyword      = "in"
	showKeyword    = "show"
	graphsKeyword  = "graphs"
	anchor         = "\"@["
	literalType    = "\"^^type:"
	literalBool    = "bool"
	literalInt     = "int64"
	literalFloat   = "float64"
	literalText    = "text"
	literalBlob    = "blob"
)
type Token struct {
	Type         TokenType
	Text         string
	ErrorMessage string
}
func (t *Token) String() string {
	return fmt.Sprintf("(%s, %s, %s)", t.Type, t.Text, t.ErrorMessage)
}
type stateFn func(*lexer) stateFn
type lexer struct {
	input         string      
	start         int         
	pos           int         
	width         int         
	line          int         
	lastLine      int         
	col           int         
	lastCol       int         
	lastTokenType TokenType   
	tokens        chan Token  
}