Add peek functions
This commit is contained in:
@@ -185,6 +185,27 @@ proc ignore*(parserFn: parserFnT): parserFnT {.inline.} =
|
||||
tokens: parser.tokens,
|
||||
))
|
||||
|
||||
proc peek*(amount: int, parserFn: parserFnT): parserFnT {.inline.} =
|
||||
## Creates parser function with a nested `parserFn`:
|
||||
## Parses using the `parserFn` but dont capture the resulting tokens and keep the current position.
|
||||
return proc(parser: Parser): ParserResult =
|
||||
let state = parser.state
|
||||
let newIndex = state.position + amount
|
||||
|
||||
let newParser = initParser(
|
||||
stream = state.stream,
|
||||
tokens = parser.tokens,
|
||||
position = newIndex,
|
||||
lastPosition = state.position,
|
||||
)
|
||||
|
||||
parserFn(newParser)
|
||||
.map(p => parser)
|
||||
|
||||
proc peek1*(parserFn: parserFnT): parserFnT = peek(1, parserFn)
|
||||
proc peekCurrent*(parserFn: parserFnT): parserFnT = peek(0, parserFn)
|
||||
proc peekBack1*(parserFn: parserFnT): parserFnT = peek(-1, parserFn)
|
||||
|
||||
proc manyUntil*(acceptFn: parserFnT, stopFn: parserFnT): parserFnT {.inline.} =
|
||||
## Creates parser function with a nested `acceptFn` parser function until the `stopFn` parserFunction is met:
|
||||
## Parses until the `stopFn` is reached or on an errror.
|
||||
@@ -330,6 +351,12 @@ when isMainModule:
|
||||
# ignore
|
||||
assert testParser123.flatMap(ignore(ch('1'))).tokensToString() == ""
|
||||
|
||||
# peek
|
||||
assert testParser123.flatMap(ch('1') + peekCurrent(ch('2')) + ch('2')).tokensToString() == "12"
|
||||
assert testParser123.flatMap(ch('1') + peekCurrent(ch('1'))).isErr() == true
|
||||
assert testParser123.flatMap(peekCurrent(startOfStream)).isOk() == true
|
||||
assert testParser123.flatMap(ch('1') + peekBack1(startOfStream)).isOk() == true
|
||||
|
||||
# manyUntil
|
||||
assert testAbc1Parser.flatMap(manyUntil(anyCh, digit)).tokensToString() == "abc"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user