1package toml 2 3import ( 4 "fmt" 5 "strconv" 6 "unicode" 7) 8 9// Define tokens 10type tokenType int 11 12const ( 13 eof = -(iota + 1) 14) 15 16const ( 17 tokenError tokenType = iota 18 tokenEOF 19 tokenComment 20 tokenKey 21 tokenString 22 tokenInteger 23 tokenTrue 24 tokenFalse 25 tokenFloat 26 tokenInf 27 tokenNan 28 tokenEqual 29 tokenLeftBracket 30 tokenRightBracket 31 tokenLeftCurlyBrace 32 tokenRightCurlyBrace 33 tokenLeftParen 34 tokenRightParen 35 tokenDoubleLeftBracket 36 tokenDoubleRightBracket 37 tokenDate 38 tokenKeyGroup 39 tokenKeyGroupArray 40 tokenComma 41 tokenColon 42 tokenDollar 43 tokenStar 44 tokenQuestion 45 tokenDot 46 tokenDotDot 47 tokenEOL 48) 49 50var tokenTypeNames = []string{ 51 "Error", 52 "EOF", 53 "Comment", 54 "Key", 55 "String", 56 "Integer", 57 "True", 58 "False", 59 "Float", 60 "Inf", 61 "NaN", 62 "=", 63 "[", 64 "]", 65 "{", 66 "}", 67 "(", 68 ")", 69 "]]", 70 "[[", 71 "Date", 72 "KeyGroup", 73 "KeyGroupArray", 74 ",", 75 ":", 76 "$", 77 "*", 78 "?", 79 ".", 80 "..", 81 "EOL", 82} 83 84type token struct { 85 Position 86 typ tokenType 87 val string 88} 89 90func (tt tokenType) String() string { 91 idx := int(tt) 92 if idx < len(tokenTypeNames) { 93 return tokenTypeNames[idx] 94 } 95 return "Unknown" 96} 97 98func (t token) Int() int { 99 if result, err := strconv.Atoi(t.val); err != nil { 100 panic(err) 101 } else { 102 return result 103 } 104} 105 106func (t token) String() string { 107 switch t.typ { 108 case tokenEOF: 109 return "EOF" 110 case tokenError: 111 return t.val 112 } 113 114 return fmt.Sprintf("%q", t.val) 115} 116 117func isSpace(r rune) bool { 118 return r == ' ' || r == '\t' 119} 120 121func isAlphanumeric(r rune) bool { 122 return unicode.IsLetter(r) || r == '_' 123} 124 125func isKeyChar(r rune) bool { 126 // Keys start with the first character that isn't whitespace or [ and end 127 // with the last non-whitespace character before the equals sign. Keys 128 // cannot contain a # character." 129 return !(r == '\r' || r == '\n' || r == eof || r == '=') 130} 131 132func isKeyStartChar(r rune) bool { 133 return !(isSpace(r) || r == '\r' || r == '\n' || r == eof || r == '[') 134} 135 136func isDigit(r rune) bool { 137 return unicode.IsNumber(r) 138} 139 140func isHexDigit(r rune) bool { 141 return isDigit(r) || 142 (r >= 'a' && r <= 'f') || 143 (r >= 'A' && r <= 'F') 144} 145