func lex(input string) *lexer {
	l := &lexer{
		input: input,
		state: lexInsideScript,
		items: make(chan item, 2),  
	}
	return l
}
lex creates a new scanner for the input string.
package base
import (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"
)
type item struct {
	typ itemType
	val string
}
func (i item) String() string {
	switch {
	case i.typ == itemEOF:
		return "EOF"
	case i.typ == itemError:
		return i.val
	case len(i.val) > 30:
		return fmt.Sprintf("%.30q...", i.val)
	}
	return fmt.Sprintf("%q", i.val)
}
type itemType int
const (
	itemError    itemType = iota  
	itemDatabase                  
	itemBool                      
	itemEOF
	itemEqual              
	itemPlusEqual          
	itemMinusEqual         
	itemColon              
	itemDot                
	itemSemiColon          
	itemComma              
	itemSendTo             
	itemLeftBrace          
	itemRightBrace         
	itemLeftParenthesis    
	itemRightParenthesis   
	itemLeftBracket        
	itemRightBracket       
	itemEqualTo            
	itemNotEqualTo         
	itemGreaterThan        
	itemGreaterThanEquals  
	itemLesserThan         
	itemLesserThanEquals   
	itemIdentifier         
	itemNumber             
	itemString             
	itemPath               
	itemOption             
	itemKeyword  
	itemNull
)
var itemName = map[itemType]string{
	itemError:             "error",
	itemBool:              "bool",
	itemDatabase:          "database",
	itemEqual:             "=",
	itemPlusEqual:         "+=",
	itemMinusEqual:        "-=",
	itemColon:             ":",
	itemDot:               ".",
	itemSemiColon:         ";",
	itemComma:             ",",
	itemSendTo:            ">>",
	itemLeftBrace:         "{",
	itemRightBrace:        "}",
	itemLeftParenthesis:   "(",
	itemRightParenthesis:  ")",
	itemLeftBracket:       "[",
	itemRightBracket:      "]",
	itemEqualTo:           "==",
	itemNotEqualTo:        "!=",
	itemGreaterThan:       ">",
	itemGreaterThanEquals: ">=",
	itemLesserThan:        "<",
	itemLesserThanEquals:  "<=",
	itemEOF:               "EOF",
	itemIdentifier:        "identifier",
	itemNumber:            "number",
	itemString:            "string",
	itemPath:              "path",
	itemOption:            "--",
	itemNull:              "null",
}
func (i itemType) String() string {
	s := itemName[i]
	if s == "" {
		return fmt.Sprintf("item%d", int(i))
	}
	return s
}
const eof = -1
type stateFn func(*lexer) stateFn
type lexer struct {
	input string     
	state stateFn    
	pos   int        
	start int        
	width int        
	items chan item  
}
func (l *lexer) next() (r rune) {
	if l.pos >= len(l.input) {
		l.width = 0
		return eof
	}
	r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
	l.pos += l.width
	return r
}
func (l *lexer) peek() rune {
	r := l.next()
	l.backup()
	return r
}
func (l *lexer) backup() {
	l.pos -= l.width
}
func (l *lexer) emit(t itemType) {
	l.items <- item{t, l.input[l.start:l.pos]}
	l.start = l.pos
}
func (l *lexer) ignore() {
	l.start = l.pos
}
func (l *lexer) accept(valid string) bool {
	if strings.IndexRune(valid, l.next()) >= 0 {
		return true
	}
	l.backup()
	return false
}
func (l *lexer) acceptRun(valid string) {
	for strings.IndexRune(valid, l.next()) >= 0 {
	}
	l.backup()
}
func (l *lexer) lineNumber() int {
	return 1 + strings.Count(l.input[:l.pos], "\n")
}
func (l *lexer) errorf(format string, args ...interface{}) stateFn {
	l.items <- item{itemError, fmt.Sprintf(format, args...)}
	return nil
}
func (l *lexer) nextItem() item {
	for {
		select {
		case item := <-l.items:
			return item
		default:
			l.state = l.state(l)
		}
	}
	panic("not reached")
}