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