github.com/lmittmann/w3@v0.20.0/internal/abi/lexer.go (about) 1 package abi 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 "unicode/utf8" 8 9 "github.com/ethereum/go-ethereum/accounts/abi" 10 ) 11 12 type item struct { 13 Typ itemType 14 Val string 15 } 16 17 type itemType int 18 19 func (i item) String() string { 20 if i.Typ == itemTypeEOF { 21 return "EOF" 22 } 23 return strconv.Quote(i.Val) 24 } 25 26 // IsType returns whether the item is a type or not. 27 func (i *item) IsType() (*abi.Type, bool) { 28 if i.Typ != itemTypeID { 29 return nil, false 30 } 31 typ, ok := types[i.Val] 32 return &typ, ok 33 } 34 35 const ( 36 // lexer item types 37 itemTypeID itemType = iota // identifier: [a-zA-Z_][0-9a-zA-Z_]* 38 itemTypePunct // punctuation: [\(\)\[\],] 39 itemTypeNum // number: [1-9][0-9]* 40 itemTypeEOF // end of file 41 42 eof rune = -1 43 44 num0 = "123456789" 45 num = "0" + num0 46 id0 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_" 47 id = id0 + num 48 space = " \t\r\n" 49 ) 50 51 // lexer holds the state of the scanner. 52 type lexer struct { 53 input string // the string being scanned 54 start int // start position of this item 55 pos int // current position in the input 56 width int // width of last rune read from input 57 } 58 59 func newLexer(input string) *lexer { 60 return &lexer{input: input} 61 } 62 63 func (l *lexer) nextItem() (*item, error) { 64 Start: 65 switch l.peek() { 66 case ' ', '\t', '\r', '\n': 67 l.acceptRun(space) 68 l.ignore() 69 goto Start 70 case '(', ')', '[', ']', ',': 71 l.next() 72 return &item{itemTypePunct, l.token()}, nil 73 case '1', '2', '3', '4', '5', '6', '7', '8', '9': 74 l.accept(num0) 75 l.acceptRun(num) 76 return &item{itemTypeNum, l.token()}, nil 77 case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_': 78 l.accept(id0) 79 l.acceptRun(id) 80 return &item{itemTypeID, l.token()}, nil 81 case eof: 82 return &item{itemTypeEOF, ""}, nil 83 default: 84 return nil, fmt.Errorf("unexpected character: %c", l.next()) 85 } 86 } 87 88 func (l *lexer) next() (next rune) { 89 if l.pos >= len(l.input) { 90 l.width = 0 91 return eof 92 } 93 next, l.width = utf8.DecodeRuneInString(l.input[l.pos:]) 94 l.pos += l.width 95 return 96 } 97 98 func (l *lexer) backup() { 99 l.pos -= l.width 100 } 101 102 func (l *lexer) ignore() { 103 l.start = l.pos 104 } 105 106 func (l *lexer) peek() (next rune) { 107 next = l.next() 108 l.backup() 109 return 110 } 111 112 func (l *lexer) accept(valid string) bool { 113 if strings.ContainsRune(valid, l.next()) { 114 return true 115 } 116 l.backup() 117 return false 118 } 119 120 // acceptRun consumes a run of runes from the valid set. 121 func (l *lexer) acceptRun(valid string) { 122 for strings.ContainsRune(valid, l.next()) { 123 } 124 l.backup() 125 } 126 127 func (l *lexer) token() string { 128 token := l.input[l.start:l.pos] 129 l.ignore() 130 return token 131 } 132 133 var types = map[string]abi.Type{ 134 "address": {T: abi.AddressTy, Size: 20}, 135 "hash": {T: abi.HashTy, Size: 32}, 136 "bool": {T: abi.BoolTy}, 137 "bytes": {T: abi.BytesTy}, 138 "string": {T: abi.StringTy}, 139 "bytes1": {T: abi.FixedBytesTy, Size: 1}, 140 "bytes2": {T: abi.FixedBytesTy, Size: 2}, 141 "bytes3": {T: abi.FixedBytesTy, Size: 3}, 142 "bytes4": {T: abi.FixedBytesTy, Size: 4}, 143 "bytes5": {T: abi.FixedBytesTy, Size: 5}, 144 "bytes6": {T: abi.FixedBytesTy, Size: 6}, 145 "bytes7": {T: abi.FixedBytesTy, Size: 7}, 146 "bytes8": {T: abi.FixedBytesTy, Size: 8}, 147 "bytes9": {T: abi.FixedBytesTy, Size: 9}, 148 "bytes10": {T: abi.FixedBytesTy, Size: 10}, 149 "bytes11": {T: abi.FixedBytesTy, Size: 11}, 150 "bytes12": {T: abi.FixedBytesTy, Size: 12}, 151 "bytes13": {T: abi.FixedBytesTy, Size: 13}, 152 "bytes14": {T: abi.FixedBytesTy, Size: 14}, 153 "bytes15": {T: abi.FixedBytesTy, Size: 15}, 154 "bytes16": {T: abi.FixedBytesTy, Size: 16}, 155 "bytes17": {T: abi.FixedBytesTy, Size: 17}, 156 "bytes18": {T: abi.FixedBytesTy, Size: 18}, 157 "bytes19": {T: abi.FixedBytesTy, Size: 19}, 158 "bytes20": {T: abi.FixedBytesTy, Size: 20}, 159 "bytes21": {T: abi.FixedBytesTy, Size: 21}, 160 "bytes22": {T: abi.FixedBytesTy, Size: 22}, 161 "bytes23": {T: abi.FixedBytesTy, Size: 23}, 162 "bytes24": {T: abi.FixedBytesTy, Size: 24}, 163 "bytes25": {T: abi.FixedBytesTy, Size: 25}, 164 "bytes26": {T: abi.FixedBytesTy, Size: 26}, 165 "bytes27": {T: abi.FixedBytesTy, Size: 27}, 166 "bytes28": {T: abi.FixedBytesTy, Size: 28}, 167 "bytes29": {T: abi.FixedBytesTy, Size: 29}, 168 "bytes30": {T: abi.FixedBytesTy, Size: 30}, 169 "bytes31": {T: abi.FixedBytesTy, Size: 31}, 170 "bytes32": {T: abi.FixedBytesTy, Size: 32}, 171 "uint8": {T: abi.UintTy, Size: 8}, 172 "uint16": {T: abi.UintTy, Size: 16}, 173 "uint24": {T: abi.UintTy, Size: 24}, 174 "uint32": {T: abi.UintTy, Size: 32}, 175 "uint40": {T: abi.UintTy, Size: 40}, 176 "uint48": {T: abi.UintTy, Size: 48}, 177 "uint56": {T: abi.UintTy, Size: 56}, 178 "uint64": {T: abi.UintTy, Size: 64}, 179 "uint72": {T: abi.UintTy, Size: 72}, 180 "uint80": {T: abi.UintTy, Size: 80}, 181 "uint88": {T: abi.UintTy, Size: 88}, 182 "uint96": {T: abi.UintTy, Size: 96}, 183 "uint104": {T: abi.UintTy, Size: 104}, 184 "uint112": {T: abi.UintTy, Size: 112}, 185 "uint120": {T: abi.UintTy, Size: 120}, 186 "uint128": {T: abi.UintTy, Size: 128}, 187 "uint136": {T: abi.UintTy, Size: 136}, 188 "uint144": {T: abi.UintTy, Size: 144}, 189 "uint152": {T: abi.UintTy, Size: 152}, 190 "uint160": {T: abi.UintTy, Size: 160}, 191 "uint168": {T: abi.UintTy, Size: 168}, 192 "uint176": {T: abi.UintTy, Size: 176}, 193 "uint184": {T: abi.UintTy, Size: 184}, 194 "uint192": {T: abi.UintTy, Size: 192}, 195 "uint200": {T: abi.UintTy, Size: 200}, 196 "uint208": {T: abi.UintTy, Size: 208}, 197 "uint216": {T: abi.UintTy, Size: 216}, 198 "uint224": {T: abi.UintTy, Size: 224}, 199 "uint232": {T: abi.UintTy, Size: 232}, 200 "uint240": {T: abi.UintTy, Size: 240}, 201 "uint248": {T: abi.UintTy, Size: 248}, 202 "uint256": {T: abi.UintTy, Size: 256}, 203 "uint": {T: abi.UintTy, Size: 256}, 204 "int8": {T: abi.IntTy, Size: 8}, 205 "int16": {T: abi.IntTy, Size: 16}, 206 "int24": {T: abi.IntTy, Size: 24}, 207 "int32": {T: abi.IntTy, Size: 32}, 208 "int40": {T: abi.IntTy, Size: 40}, 209 "int48": {T: abi.IntTy, Size: 48}, 210 "int56": {T: abi.IntTy, Size: 56}, 211 "int64": {T: abi.IntTy, Size: 64}, 212 "int72": {T: abi.IntTy, Size: 72}, 213 "int80": {T: abi.IntTy, Size: 80}, 214 "int88": {T: abi.IntTy, Size: 88}, 215 "int96": {T: abi.IntTy, Size: 96}, 216 "int104": {T: abi.IntTy, Size: 104}, 217 "int112": {T: abi.IntTy, Size: 112}, 218 "int120": {T: abi.IntTy, Size: 120}, 219 "int128": {T: abi.IntTy, Size: 128}, 220 "int136": {T: abi.IntTy, Size: 136}, 221 "int144": {T: abi.IntTy, Size: 144}, 222 "int152": {T: abi.IntTy, Size: 152}, 223 "int160": {T: abi.IntTy, Size: 160}, 224 "int168": {T: abi.IntTy, Size: 168}, 225 "int176": {T: abi.IntTy, Size: 176}, 226 "int184": {T: abi.IntTy, Size: 184}, 227 "int192": {T: abi.IntTy, Size: 192}, 228 "int200": {T: abi.IntTy, Size: 200}, 229 "int208": {T: abi.IntTy, Size: 208}, 230 "int216": {T: abi.IntTy, Size: 216}, 231 "int224": {T: abi.IntTy, Size: 224}, 232 "int232": {T: abi.IntTy, Size: 232}, 233 "int240": {T: abi.IntTy, Size: 240}, 234 "int248": {T: abi.IntTy, Size: 248}, 235 "int256": {T: abi.IntTy, Size: 256}, 236 "int": {T: abi.IntTy, Size: 256}, 237 }