func (l *tomlLexer) lexKey() tomlLexStateFn {
	growingString := ""
	for r := l.peek(); isKeyChar(r) || r == '\n' || r == '\r'; r = l.peek() {
		if r == '"' {
			l.next()
			str, err := l.lexStringAsString(`"`, false, true)
			if err != nil {
				return l.errorf(err.Error())
			}
			growingString += str
			l.next()
			continue
		} else if r == '\'' {
			l.next()
			str, err := l.lexLiteralStringAsString(`'`, false)
			if err != nil {
				return l.errorf(err.Error())
			}
			growingString += str
			l.next()
			continue
		} else if r == '\n' {
			return l.errorf("keys cannot contain new lines")
		} else if isSpace(r) {
			break
		} else if !isValidBareChar(r) {
			return l.errorf("keys cannot contain %c character", r)
		}
		growingString += string(r)
		l.next()
	}
	l.emitWithValue(tokenKey, growingString)
	return l.lexVoid
}
Parse the key and emits its value without escape sequences.
bare keys, basic string keys and literal string keys are supported.
package toml
import (
	"bytes"
	"errors"
	"fmt"
	"regexp"
	"strconv"
	"strings"
)
var dateRegexp *regexp.Regexp
type tomlLexStateFn func() tomlLexStateFn
type tomlLexer struct {
	inputIdx          int
	input             []rune  
	currentTokenStart int
	currentTokenStop  int
	tokens            []token
	depth             int
	line              int
	col               int
	endbufferLine     int
	endbufferCol      int
}
func (l *tomlLexer) read() rune {
	r := l.peek()
	if r == '\n' {
		l.endbufferLine++
		l.endbufferCol = 1
	} else {
		l.endbufferCol++
	}
	l.inputIdx++
	return r
}
func (l *tomlLexer) next() rune {
	r := l.read()
	if r != eof {
		l.currentTokenStop++
	}
	return r
}
func (l *tomlLexer) ignore() {
	l.currentTokenStart = l.currentTokenStop
	l.line = l.endbufferLine
	l.col = l.endbufferCol
}
func (l *tomlLexer) skip() {
	l.next()
	l.ignore()
}
func (l *tomlLexer) fastForward(n int) {
	for i := 0; i < n; i++ {
		l.next()
	}
}
func (l *tomlLexer) emitWithValue(t tokenType, value string) {
	l.tokens = append(l.tokens, token{
		Position: Position{l.line, l.col},
		typ:      t,
		val:      value,
	})
	l.ignore()
}
func (l *tomlLexer) emit(t tokenType) {
	l.emitWithValue(t, string(l.input[l.currentTokenStart:l.currentTokenStop]))
}
func (l *tomlLexer) peek() rune {
	if l.inputIdx >= len(l.input) {
		return eof
	}
	return l.input[l.inputIdx]
}
func (l *tomlLexer) peekString(size int) string {
	maxIdx := len(l.input)
	upperIdx := l.inputIdx + size  
	if upperIdx > maxIdx {
		upperIdx = maxIdx
	}
	return string(l.input[l.inputIdx:upperIdx])
}
func (l *tomlLexer) follow(next string) bool {
	return next == l.peekString(len(next))
}
func (l *tomlLexer) errorf(format string, args ...interface{}) tomlLexStateFn {
	l.tokens = append(l.tokens, token{
		Position: Position{l.line, l.col},
		typ:      tokenError,
		val:      fmt.Sprintf(format, args...),
	})
	return nil
}
func (l *tomlLexer) lexVoid() tomlLexStateFn {
	for {
		next := l.peek()
		switch next {
		case '[':
			return l.lexTableKey
		case '#':
			return l.lexComment(l.lexVoid)
		case '=':
			return l.lexEqual
		case '\r':
			fallthrough
		case '\n':
			l.skip()
			continue
		}
		if isSpace(next) {
			l.skip()
		}
		if l.depth > 0 {
			return l.lexRvalue
		}
		if isKeyStartChar(next) {
			return l.lexKey
		}
		if next == eof {
			l.next()
			break
		}
	}
	l.emit(tokenEOF)
	return nil
}
func (l *tomlLexer) lexRvalue() tomlLexStateFn {
	for {
		next := l.peek()
		switch next {
		case '.':
			return l.errorf("cannot start float with a dot")
		case '=':
			return l.lexEqual
		case '[':
			l.depth++
			return l.lexLeftBracket
		case ']':
			l.depth--
			return l.lexRightBracket
		case '{':
			return l.lexLeftCurlyBrace
		case '}':
			return l.lexRightCurlyBrace
		case '#':
			return l.lexComment(l.lexRvalue)
		case '"':
			return l.lexString
		case '\'':
			return l.lexLiteralString
		case ',':
			return l.lexComma
		case '\r':
			fallthrough
		case '\n':
			l.skip()
			if l.depth == 0 {
				return l.lexVoid
			}
			return l.lexRvalue
		case '_':
			return l.errorf("cannot start number with underscore")
		}
		if l.follow("true") {
			return l.lexTrue
		}
		if l.follow("false") {
			return l.lexFalse
		}
		if l.follow("inf") {
			return l.lexInf
		}
		if l.follow("nan") {
			return l.lexNan
		}
		if isSpace(next) {
			l.skip()
			continue
		}
		if next == eof {
			l.next()
			break
		}
		possibleDate := l.peekString(35)
		dateMatch := dateRegexp.FindString(possibleDate)
		if dateMatch != "" {
			l.fastForward(len(dateMatch))
			return l.lexDate
		}
		if next == '+' || next == '-' || isDigit(next) {
			return l.lexNumber
		}
		if isAlphanumeric(next) {
			return l.lexKey
		}
		return l.errorf("no value can start with %c", next)
	}
	l.emit(tokenEOF)
	return nil
}
func (l *tomlLexer) lexLeftCurlyBrace() tomlLexStateFn {
	l.next()
	l.emit(tokenLeftCurlyBrace)
	return l.lexRvalue
}
func (l *tomlLexer) lexRightCurlyBrace() tomlLexStateFn {
	l.next()
	l.emit(tokenRightCurlyBrace)
	return l.lexRvalue
}
func (l *tomlLexer) lexDate() tomlLexStateFn {
	l.emit(tokenDate)
	return l.lexRvalue
}
func (l *tomlLexer) lexTrue() tomlLexStateFn {
	l.fastForward(4)
	l.emit(tokenTrue)
	return l.lexRvalue
}
func (l *tomlLexer) lexFalse() tomlLexStateFn {
	l.fastForward(5)
	l.emit(tokenFalse)
	return l.lexRvalue
}
func (l *tomlLexer) lexInf() tomlLexStateFn {
	l.fastForward(3)
	l.emit(tokenInf)
	return l.lexRvalue
}
func (l *tomlLexer) lexNan() tomlLexStateFn {
	l.fastForward(3)
	l.emit(tokenNan)
	return l.lexRvalue
}
func (l *tomlLexer) lexEqual() tomlLexStateFn {
	l.next()
	l.emit(tokenEqual)
	return l.lexRvalue
}
func (l *tomlLexer) lexComma() tomlLexStateFn {
	l.next()
	l.emit(tokenComma)
	return l.lexRvalue
}