# lexer 原理解釋

run 之中放著 State Function 迴圈

=stateFn=定義如下:

```type stateFn func(*Lexer) stateFn
```

```void LexAll(int state) {
switch(state) {
case number:
LexNumber();
case alphabra:
LexIdentifier();
// ...
}
}
```

```func lexWhiteSpace(l *Lexer) stateFn {
for r := l.next(); isSpace(r) || r=='\n'; l.next() {
r = l.peek()
}
l.backup() // break mount's rune is not a space
l.ignore() // because no emit, we need ignore will mount's pos runes

switch r := l.next(); {
case r == EOF:
l.emit(ItemEOF)
return nil
// ...
case r == '=':
return lexEqualOp // =, ==
case r == ':':
l.emit(ItemColon)
return lexWhiteSpace
case r == '"' || r == '`' || r == '\'':
return lexString // "string literal", `string literal`
case '0' <= r && r <= '9':
return lexNumber // 12323, 2.344
case isAlphaNumeric(r):
return lexIdentifiers // car, car_build
default:
panic(fmt.Sprintf("Don't know how to do with: %q", r))
}
}
```

```func lexNumber(l *Lexer) stateFn {
firstDot := true
for r := l.next(); ( '0' <= r && r <= '9' ) || r == '.'; r = l.next() {
if r == '.' {
if firstDot {
firstDot = false
} else {
break
}
}
}
l.backup()

l.emit(ItemNumber)
return lexWhiteSpace
}
```

```func (l *Lexer) run() {
for l.state = lexWhiteSpace; l.state != nil; {
l.state = l.state(l)
}
close(l.items)
}
// 得到一個狀態函數參考，然後執行狀態函數，就這麼簡單
// l.state是一個stateFn
```

Date: 2017-07-08 Sat 00:00