Implement anyUntil using endOfStream

This commit is contained in:
Florian Schroedl
2022-01-20 17:00:00 +01:00
parent 1d7d669146
commit dfb4baa8c8

View File

@@ -173,6 +173,17 @@ func ch(expectedChar: char): (Parser -> ParserResult) {.inline.} =
parser: parser, parser: parser,
)) ))
proc endOfStream(parser: Parser): ParserResult =
if parser.state.position == parser.state.stream.len - 1:
ok(parser)
else:
err(ParserError(
kind: endOfStringErr,
expected: &"EndOfString",
index: parser.state.position,
parser: parser,
))
func ignore(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} = func ignore(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
## Parse characters but throw success tokens away ## Parse characters but throw success tokens away
return proc(parser: Parser): ParserResult = return proc(parser: Parser): ParserResult =
@@ -190,6 +201,9 @@ func manyUntil(acceptFn: Parser -> ParserResult, stopFn: Parser -> ParserResult)
res = res.flatMap(acceptFn) res = res.flatMap(acceptFn)
return res return res
func anyUntil(stopFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
manyUntil(ch(AllChars), stopFn)
proc parseSeq(parser: ParserResult, xs: seq[Parser -> ParserResult]): ParserResult = proc parseSeq(parser: ParserResult, xs: seq[Parser -> ParserResult]): ParserResult =
xs.foldl(a.flatMap(b), parser) xs.foldl(a.flatMap(b), parser)
@@ -212,31 +226,33 @@ proc foldTokens[T](
onError(err) onError(err)
when isMainModule: when isMainModule:
let fooParser = initParser("FOO___BAR") # let fooParser = initParser("FOO___BAR")
.parseSeq(@[ # .parseSeq(@[
str("FOO"), # str("FOO"),
ignore(str("___")), # ignore(str("___")),
ch('B'), # ch('B'),
ch('B'), # ch('B'),
ch('A'), # ch('A'),
ch('R'), # ch('R'),
]) # ])
.foldTokens( # .foldTokens(
err => $err, # err => $err,
xs => xs.foldl(a & b.value, "") # xs => xs.foldl(a & b.value, "")
) # )
# echo fooParser
let manUntilTest = initParser("AAAB")
.flatMap(manyUntil(ch('B'), ch('B')))
echo initParser("**** Foo")
.parseSeq(@[ echo initParser("_FOO___BAR").parseSeq(@[
manyUntil(ch('*'), ch(' ')), anyUntil(endOfStream),
ignore(ch ' '),
str("Foo")
]) ])
# .parseSeq(@[
# manyUntil(ch('*'), ch(' ')),
# ignore(ch ' '),
# str("Foo")
# ])
# echo initParser("AAAB").flatMap(ch 'b') # echo initParser("AAAB").flatMap(ch 'b')
# # .flatMap(ch('A')) # # .flatMap(ch('A'))
# # .flatMap(ch('B')) # # .flatMap(ch('B'))