diff options
Diffstat (limited to 'combinator.go')
-rw-r--r-- | combinator.go | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/combinator.go b/combinator.go index d7be3f9..4e7e4a5 100644 --- a/combinator.go +++ b/combinator.go @@ -26,7 +26,7 @@ func NoAutoWS(parser Parserish) Parser { parserfied := Parsify(parser) return func(ps *State, node *Result) { oldWS := ps.WS - ps.WS = func(ps *State) {} + ps.WS = NoWhitespace parserfied(ps, node) ps.WS = oldWS } @@ -145,6 +145,36 @@ func Maybe(parser Parserish) Parser { }) } +// Until will consume all input until one of the given parsers match. This is running every parser over every byte, +// so its probably going to be slow. +func Until(parsers ...Parserish) Parser { + parserfied := ParsifyAll(parsers...) + return NewParser("Until()", func(ps *State, node *Result) { + ws := ps.WS + ps.WS = NoWhitespace + defer func() { + ps.WS = ws + }() + startPos := ps.Pos + for ps.Pos < len(ps.Input) { + endPos := ps.Pos + for _, p := range parserfied { + ps.Pos = endPos + + p(ps, node) + + if !ps.Errored() { + node.Token = ps.Input[startPos:endPos] + return + } + ps.Recover() + } + ps.Pos++ + } + node.Token = ps.Input[startPos:ps.Pos] + }) +} + // Bind will set the node .Result when the given parser matches // This is useful for giving a value to keywords and constant literals // like true and false. See the json parser for an example. |