package methodfunc import ( "unicode" ) const ( tokenBy = "By" tokenWildcard = "Wildcard" // should be followed by "By", ) // word lexer, not characters. type lexer struct { words []string cur int } func newLexer(s string) *lexer { l := new(lexer) l.reset(s) return l } func (l *lexer) reset(trailing string) { l.cur = -1 var words []string if trailing != "" { end := len(trailing) start := -1 for i, n := 0, end; i < n; i++ { c := rune(trailing[i]) if unicode.IsUpper(c) { // it doesn't count the last uppercase if start != -1 { end = i words = append(words, trailing[start:end]) } start = i continue } end = i + 1 } if end > 0 && len(trailing) >= end { words = append(words, trailing[start:end]) } } l.words = words } func (l *lexer) next() (w string) { cur := l.cur + 1 if w = l.peek(cur); w != "" { l.cur++ } return } func (l *lexer) skip() { if cur := l.cur + 1; cur < len(l.words) { l.cur = cur } else { l.cur = len(l.words) - 1 } } func (l *lexer) peek(idx int) string { if idx < len(l.words) { return l.words[idx] } return "" } func (l *lexer) peekNext() (w string) { return l.peek(l.cur + 1) } func (l *lexer) peekPrev() (w string) { if l.cur > 0 { cur := l.cur - 1 w = l.words[cur] } return w }