nextToken picks out the next token from the input
()
| 703 | |
| 704 | // nextToken picks out the next token from the input |
| 705 | func (t *Tokenizer) nextToken() (models.Token, error) { |
| 706 | if t.pos.Index >= len(t.input) { |
| 707 | return models.Token{Type: models.TokenTypeEOF}, nil |
| 708 | } |
| 709 | |
| 710 | // Fast path for common cases |
| 711 | r, _ := utf8.DecodeRune(t.input[t.pos.Index:]) |
| 712 | switch { |
| 713 | case isIdentifierStart(r): |
| 714 | return t.readIdentifier() |
| 715 | case r >= '0' && r <= '9': |
| 716 | return t.readNumber(nil) |
| 717 | case r == '"' || isUnicodeQuote(r): |
| 718 | return t.readQuotedIdentifier() |
| 719 | case r == '`': |
| 720 | // MySQL-style backtick identifier |
| 721 | return t.readBacktickIdentifier() |
| 722 | case r == '\'' || r == '\u2018' || r == '\u2019' || r == '\u00AB' || r == '\u00BB': |
| 723 | return t.readQuotedString(r) |
| 724 | } |
| 725 | |
| 726 | // Slower path for punctuation and operators |
| 727 | return t.readPunctuation() |
| 728 | } |
| 729 | |
| 730 | // isIdentifierStart checks if a rune can start an identifier |
| 731 | func isIdentifierStart(r rune) bool { |
no test coverage detected