const TOK_CMD = 100
var parser = tokenizer.New()
parser.DefineTokens(TOK_CMD, []string{"CMD"})
stream := parser.ParseSting("CMD CMD")
ok := stream.IsNextSequence(TOK_CMD, TOK_CMD, TOK_CMD, TOK_CMD)
// here it is stuck forever
Where the problem lies is the code of func (s *Stream) IsNextSequence(keys ...TokenKey) bool and func (s *Stream) GoTo(id int) *Stream
// IsNextSequence checks if these are next tokens in exactly the same sequence as specified.
func (s *Stream) IsNextSequence(keys ...TokenKey) bool {
var (
result = true
hSize = 0
id = s.CurrentToken().ID()
)
if s.historySize > 0 && s.historySize < len(keys) {
hSize = s.historySize
s.historySize = len(keys)
}
for _, key := range keys {
// at the moment of parsing the second "CMD" s.GoNext().CurrentToken() is going to be undefToken
if !s.GoNext().CurrentToken().Is(key) {
result = false
break
}
}
s.GoTo(id)
if hSize != 0 {
s.SetHistorySize(hSize)
}
return result
}
func (s *Stream) GoTo(id int) *Stream {
// s.current is undefToken, thus s.current.id is -1
// but the id of the token, which was pointed by s.current at the moment s.IsNextSequence(...) was called is 0
// this leads to condition `id > s.current.id` to be always true in infinite cycle
if id > s.current.id {
for s.current != nil && id != s.current.id {
s.GoNext()
}
} else if id < s.current.id {
for s.current != nil && id != s.current.id {
s.GoPrev()
}
}
return s
}
Using
github.com/bzick/tokenizer v1.4.0
Way to meet the issue:
Where the problem lies is the code of
func (s *Stream) IsNextSequence(keys ...TokenKey) bool
andfunc (s *Stream) GoTo(id int) *Stream