diff --git a/src/parser/parser.nim b/src/parser/parser.nim index f9f607d..aefa906 100644 --- a/src/parser/parser.nim +++ b/src/parser/parser.nim @@ -203,6 +203,16 @@ func ignore*(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inlin 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.} = ## Parse characters but throw success tokens away return proc(parser: Parser): ParserResult = @@ -241,6 +251,7 @@ func choice*(parsers: seq[Parser -> ParserResult]): (Parser -> ParserResult) {.i proc(x: ParserResult): ParserResult = x, ) + proc parseSeq*(parser: ParserResult, xs: seq[Parser -> ParserResult]): ParserResult = xs.foldl(a.flatMap(b), parser) @@ -307,35 +318,10 @@ proc foldBuilder*[T, T2]( onError(err[1]) when isMainModule: - let parseHeadingStars = @[ - manyUntil(ch('*'), ch(' ')), - ignore(ch(' ')) + let optionalPrefixParser = @[ + optional(ch('_')), + str("ABC") ] - let parseHeadingText = @[ - anyUntil(endOfStream), - ] - - 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 + echo initParserResult("_ABC").parseSeq(optionalPrefixParser) + echo initParserResult("ABC").parseSeq(optionalPrefixParser)