From 0f854720ca2bad30246020bb01cdb903a5f9406d Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Tue, 15 Aug 2017 18:57:00 +1000 Subject: Make until only work on string terminators --- parser.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'parser.go') diff --git a/parser.go b/parser.go index fecf635..a612857 100644 --- a/parser.go +++ b/parser.go @@ -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] + }) +} -- cgit v1.2.3