github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/asm/lexer.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:34</date> 10 //</624450077330509824> 11 12 13 package asm 14 15 import ( 16 "fmt" 17 "os" 18 "strings" 19 "unicode" 20 "unicode/utf8" 21 ) 22 23 //statefn在 24 //lexer解析 25 //当前状态。 26 type stateFn func(*lexer) stateFn 27 28 //当lexer发现 29 //一种新的可分割代币。这些都送过去了 30 //词汇的标记通道 31 type token struct { 32 typ tokenType 33 lineno int 34 text string 35 } 36 37 //tokentype是lexer的不同类型 38 //能够解析并返回。 39 type tokenType int 40 41 const ( 42 eof tokenType = iota //文件结束 43 lineStart //行开始时发出 44 lineEnd //行结束时发出 45 invalidStatement //任何无效的语句 46 element //元素分析期间的任何元素 47 label //找到标签时发出标签 48 labelDef //找到新标签时发出标签定义 49 number //找到数字时发出数字 50 stringValue //当找到字符串时,将发出StringValue 51 52 Numbers = "1234567890" //表示任何十进制数的字符 53 HexadecimalNumbers = Numbers + "aAbBcCdDeEfF" //表示任何十六进制的字符 54 Alpha = "abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ" //表示字母数字的字符 55 ) 56 57 //字符串实现字符串 58 func (it tokenType) String() string { 59 if int(it) > len(stringtokenTypes) { 60 return "invalid" 61 } 62 return stringtokenTypes[it] 63 } 64 65 var stringtokenTypes = []string{ 66 eof: "EOF", 67 invalidStatement: "invalid statement", 68 element: "element", 69 lineEnd: "end of line", 70 lineStart: "new line", 71 label: "label", 72 labelDef: "label definition", 73 number: "number", 74 stringValue: "string", 75 } 76 77 //lexer是解析的基本构造 78 //源代码并将其转换为令牌。 79 //标记由编译器解释。 80 type lexer struct { 81 input string //输入包含程序的源代码 82 83 tokens chan token //令牌用于将令牌传递给侦听器 84 state stateFn //当前状态函数 85 86 lineno int //源文件中的当前行号 87 start, pos, width int //词法和返回值的位置 88 89 debug bool //触发调试输出的标志 90 } 91 92 //lex使用给定的源按名称对程序进行lex。它返回一个 93 //传递令牌的通道。 94 func Lex(name string, source []byte, debug bool) <-chan token { 95 ch := make(chan token) 96 l := &lexer{ 97 input: string(source), 98 tokens: ch, 99 state: lexLine, 100 debug: debug, 101 } 102 go func() { 103 l.emit(lineStart) 104 for l.state != nil { 105 l.state = l.state(l) 106 } 107 l.emit(eof) 108 close(l.tokens) 109 }() 110 111 return ch 112 } 113 114 //next返回程序源中的下一个rune。 115 func (l *lexer) next() (rune rune) { 116 if l.pos >= len(l.input) { 117 l.width = 0 118 return 0 119 } 120 rune, l.width = utf8.DecodeRuneInString(l.input[l.pos:]) 121 l.pos += l.width 122 return rune 123 } 124 125 //备份备份最后一个已分析的元素(多字符) 126 func (l *lexer) backup() { 127 l.pos -= l.width 128 } 129 130 //Peek返回下一个符文,但不前进搜索者 131 func (l *lexer) peek() rune { 132 r := l.next() 133 l.backup() 134 return r 135 } 136 137 //忽略推进搜索者并忽略值 138 func (l *lexer) ignore() { 139 l.start = l.pos 140 } 141 142 //接受检查给定输入是否与下一个rune匹配 143 func (l *lexer) accept(valid string) bool { 144 if strings.ContainsRune(valid, l.next()) { 145 return true 146 } 147 148 l.backup() 149 150 return false 151 } 152 153 //acceptrun将继续推进seeker直到有效 154 //再也见不到了。 155 func (l *lexer) acceptRun(valid string) { 156 for strings.ContainsRune(valid, l.next()) { 157 } 158 l.backup() 159 } 160 161 //acceptrununtil是acceptrun的倒数,将继续 162 //把探索者推进直到找到符文。 163 func (l *lexer) acceptRunUntil(until rune) bool { 164 //继续运行,直到找到符文 165 for i := l.next(); !strings.ContainsRune(string(until), i); i = l.next() { 166 if i == 0 { 167 return false 168 } 169 } 170 171 return true 172 } 173 174 //blob返回当前值 175 func (l *lexer) blob() string { 176 return l.input[l.start:l.pos] 177 } 178 179 //向令牌通道发送新令牌以进行处理 180 func (l *lexer) emit(t tokenType) { 181 token := token{t, l.lineno, l.blob()} 182 183 if l.debug { 184 fmt.Fprintf(os.Stderr, "%04d: (%-20v) %s\n", token.lineno, token.typ, token.text) 185 } 186 187 l.tokens <- token 188 l.start = l.pos 189 } 190 191 //lexline是用于词法处理行的状态函数 192 func lexLine(l *lexer) stateFn { 193 for { 194 switch r := l.next(); { 195 case r == '\n': 196 l.emit(lineEnd) 197 l.ignore() 198 l.lineno++ 199 200 l.emit(lineStart) 201 case r == ';' && l.peek() == ';': 202 return lexComment 203 case isSpace(r): 204 l.ignore() 205 case isLetter(r) || r == '_': 206 return lexElement 207 case isNumber(r): 208 return lexNumber 209 case r == '@': 210 l.ignore() 211 return lexLabel 212 case r == '"': 213 return lexInsideString 214 default: 215 return nil 216 } 217 } 218 } 219 220 //lexcomment分析当前位置直到结束 221 //并丢弃文本。 222 func lexComment(l *lexer) stateFn { 223 l.acceptRunUntil('\n') 224 l.ignore() 225 226 return lexLine 227 } 228 229 //lexmlabel解析当前标签,发出并返回 230 //lex文本状态函数用于推进分析 231 //过程。 232 func lexLabel(l *lexer) stateFn { 233 l.acceptRun(Alpha + "_") 234 235 l.emit(label) 236 237 return lexLine 238 } 239 240 //lexinsideString对字符串内部进行lexi,直到 241 //state函数查找右引号。 242 //它返回lex文本状态函数。 243 func lexInsideString(l *lexer) stateFn { 244 if l.acceptRunUntil('"') { 245 l.emit(stringValue) 246 } 247 248 return lexLine 249 } 250 251 func lexNumber(l *lexer) stateFn { 252 acceptance := Numbers 253 if l.accept("0") || l.accept("xX") { 254 acceptance = HexadecimalNumbers 255 } 256 l.acceptRun(acceptance) 257 258 l.emit(number) 259 260 return lexLine 261 } 262 263 func lexElement(l *lexer) stateFn { 264 l.acceptRun(Alpha + "_" + Numbers) 265 266 if l.peek() == ':' { 267 l.emit(labelDef) 268 269 l.accept(":") 270 l.ignore() 271 } else { 272 l.emit(element) 273 } 274 return lexLine 275 } 276 277 func isLetter(t rune) bool { 278 return unicode.IsLetter(t) 279 } 280 281 func isSpace(t rune) bool { 282 return unicode.IsSpace(t) 283 } 284 285 func isNumber(t rune) bool { 286 return unicode.IsNumber(t) 287 } 288