Add optional parser method
This commit is contained in:
@@ -203,6 +203,16 @@ func ignore*(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inlin
|
|||||||
tokens: parser.tokens,
|
tokens: parser.tokens,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
func optional*(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
|
||||||
|
## Parse characters and ignore failure
|
||||||
|
return proc(parser: Parser): ParserResult =
|
||||||
|
let newParser = parserFn(parser)
|
||||||
|
|
||||||
|
if newParser.isOk():
|
||||||
|
newParser
|
||||||
|
else:
|
||||||
|
parser.ok()
|
||||||
|
|
||||||
func manyUntil*(acceptFn: Parser -> ParserResult, stopFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
|
func manyUntil*(acceptFn: Parser -> ParserResult, stopFn: 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 =
|
||||||
@@ -241,6 +251,7 @@ func choice*(parsers: seq[Parser -> ParserResult]): (Parser -> ParserResult) {.i
|
|||||||
proc(x: ParserResult): ParserResult = x,
|
proc(x: ParserResult): ParserResult = x,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
@@ -307,35 +318,10 @@ proc foldBuilder*[T, T2](
|
|||||||
onError(err[1])
|
onError(err[1])
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
let parseHeadingStars = @[
|
let optionalPrefixParser = @[
|
||||||
manyUntil(ch('*'), ch(' ')),
|
optional(ch('_')),
|
||||||
ignore(ch(' '))
|
str("ABC")
|
||||||
]
|
]
|
||||||
|
|
||||||
let parseHeadingText = @[
|
echo initParserResult("_ABC").parseSeq(optionalPrefixParser)
|
||||||
anyUntil(endOfStream),
|
echo initParserResult("ABC").parseSeq(optionalPrefixParser)
|
||||||
]
|
|
||||||
|
|
||||||
type StringBuilderT = string
|
|
||||||
type StringBuilder = Builder[StringBuilderT]
|
|
||||||
type StringBuilderResult = BuilderResult[StringBuilderT]
|
|
||||||
proc stringConcat(typeInfo: StringBuilderT):
|
|
||||||
(seq[Token], seq[StringBuilderT]) -> seq[StringBuilderT] =
|
|
||||||
return proc(xs: seq[Token], ys: seq[StringBuilderT]): seq[StringBuilderT] =
|
|
||||||
return ys & xs.foldl(a & b.value, typeInfo)
|
|
||||||
|
|
||||||
let sampleBuilder = StringBuilderResult
|
|
||||||
.ok(StringBuilder((
|
|
||||||
parser: initParser("**** Some stars"),
|
|
||||||
tree: newSeq[StringBuilderT](),
|
|
||||||
)))
|
|
||||||
.applyParsersSeq(@[
|
|
||||||
(parseHeadingStars, stringConcat("Stars: ")),
|
|
||||||
(parseHeadingText, stringConcat("Text: "))
|
|
||||||
])
|
|
||||||
.foldBuilder(
|
|
||||||
err => &"Error Parsing: {err}",
|
|
||||||
xs => "Parser Succesfull:\n" & xs.join("\n"),
|
|
||||||
)
|
|
||||||
|
|
||||||
echo sampleBuilder
|
|
||||||
|
|||||||
Reference in New Issue
Block a user