diff options
author | Adam Scarr <adam@vektah.net> | 2017-08-15 18:57:00 +1000 |
---|---|---|
committer | Adam Scarr <adam@vektah.net> | 2017-08-15 18:57:00 +1000 |
commit | 0f854720ca2bad30246020bb01cdb903a5f9406d (patch) | |
tree | f4acedaa6928300fecd7791a68cc493c37938e5e /parser.go | |
parent | ddb61bdfc034a683f755dec6ddc80627d2d43522 (diff) |
Make until only work on string terminators
Diffstat (limited to 'parser.go')
-rw-r--r-- | parser.go | 25 |
1 files changed, 24 insertions, 1 deletions
@@ -200,7 +200,7 @@ func Chars(matcher string, repetition ...int) Parser { } // NotChars accepts the full range of input from Chars, but it will stop when any -// character matches. +// character matches. If you need to match until you see a sequence use Until instead func NotChars(matcher string, repetition ...int) Parser { return NewParser("!["+matcher+"]", charsImpl(matcher, true, repetition...)) } @@ -244,3 +244,26 @@ func charsImpl(matcher string, stopOn bool, repetition ...int) Parser { ps.Advance(matched) } } + +// Until will consume all input until one of the given terminator sequences is found. If you want to stop when seeing +// single characters see NotChars instead +func Until(terminators ...string) Parser { + + return NewParser("Until", func(ps *State, node *Result) { + startPos := ps.Pos + loop: + for ps.Pos < len(ps.Input) { + for _, terminator := range terminators { + if ps.Pos+len(terminator) <= len(ps.Input) && ps.Input[ps.Pos:ps.Pos+len(terminator)] == terminator { + break loop + } + } + ps.Pos++ + } + + if ps.Pos == startPos { + ps.ErrorHere("something") + } + node.Token = ps.Input[startPos:ps.Pos] + }) +} |