Parser transformation
This commit is contained in:
102
src/test.nim
102
src/test.nim
@@ -37,7 +37,7 @@ type
|
||||
ParserResult* = Result[Parser, ParserError]
|
||||
|
||||
Builder*[T] = tuple[
|
||||
parser: ParserResult,
|
||||
parser: Parser,
|
||||
tree: seq[T]
|
||||
]
|
||||
BuilderResult*[T] = Result[Builder[T], (Builder[T], string)]
|
||||
@@ -109,7 +109,7 @@ proc `$`*(x: ParserError): string =
|
||||
{errSpace}^ Expected '{expected}' but got '{unexpected}'"""
|
||||
else: "ParseError"
|
||||
|
||||
proc initParser(str: string): ParserResult =
|
||||
proc initParser(str: string): Parser =
|
||||
Parser(
|
||||
state: ParserState(
|
||||
stream: str,
|
||||
@@ -117,7 +117,7 @@ proc initParser(str: string): ParserResult =
|
||||
lastPosition: 0,
|
||||
),
|
||||
tokens: newSeq[Token](),
|
||||
).ok()
|
||||
)
|
||||
|
||||
func ch(expectedChars: set[char]): (Parser -> ParserResult) {.inline.} =
|
||||
return func(parser: Parser): ParserResult =
|
||||
@@ -262,67 +262,71 @@ proc foldTokens[T](
|
||||
let err = parserResult.error()
|
||||
onError(err)
|
||||
|
||||
proc merge[T](t: Builder[T], parser: Parser, tree: seq[T]): Builder[T] =
|
||||
Builder[T]((
|
||||
parser,
|
||||
tree
|
||||
))
|
||||
|
||||
# proc mapTree[T](builder: BuilderResult[T], fn: Builder[T] -> Builder[T]) =
|
||||
# builder.map(proc(b: Builder) =
|
||||
# (@parser, @builder) := builder
|
||||
# b
|
||||
# )
|
||||
proc applyParsers[T](
|
||||
builder: Builder[T],
|
||||
parsers: seq[Parser -> ParserResult],
|
||||
tokenFoldFn: (seq[Token], seq[T]) -> seq[T],
|
||||
): BuilderResult[T] =
|
||||
# proc nested(b: Builder[T]): BuilderResult[T] =
|
||||
let newParser = ParserResult.ok(Parser(
|
||||
state: builder[0].state,
|
||||
tokens: @[]
|
||||
))
|
||||
.parseSeq(parsers)
|
||||
|
||||
# proc applyParserTokens[T](builder: BuilderResult, fn: seq[Token] -> T): BuilderResult =
|
||||
# (@parser, @builder) := builder
|
||||
# parser.foldTokens(
|
||||
# proc(x: ParserError): BuilderResult = err(x),
|
||||
# proc(xs: seq[Token]): BuilderResult = ok(parser, builder.map()),
|
||||
# )
|
||||
newParser
|
||||
.foldTokens(
|
||||
(err: ParserError) => BuilderResult[T].err((builder, "foo")),
|
||||
(newTokens: seq[Token]) => BuilderResult[T].ok(
|
||||
builder.merge(newParser.unsafeGet(), tokenFoldFn(newTokens, builder[1]))
|
||||
),
|
||||
)
|
||||
|
||||
proc mapTree[T](builder: BuilderResult[T], fn: seq[T] -> seq[T]): BuilderResult[T] =
|
||||
builder.map(proc(b: Builder[T]): Builder[T] = Builder((
|
||||
parser: b[0],
|
||||
tree: fn(b[1]),
|
||||
)))
|
||||
|
||||
|
||||
when isMainModule:
|
||||
# let fooParser = initParser("FOO___BAR")
|
||||
# .parseSeq(@[
|
||||
# str("FOO"),
|
||||
# ignore(str("___")),
|
||||
# ch('B'),
|
||||
# ch('B'),
|
||||
# ch('A'),
|
||||
# ch('R'),
|
||||
# ])
|
||||
# .foldTokens(
|
||||
# err => $err,
|
||||
# xs => xs.foldl(a & b.value, "")
|
||||
# )
|
||||
|
||||
# echo initParser("BB").parseSeq(@[
|
||||
# choice(@[ch(Digits), ch('B')]),
|
||||
# ])
|
||||
|
||||
let parseHeadingStars = @[
|
||||
manyUntil(ch('*'), ch(' ')),
|
||||
ignore(ch(' '))
|
||||
]
|
||||
# proc buildHeadingStars(stars: ParserResult, builder: OrgElement): OrgElement =
|
||||
# builder.level = stars.get().len
|
||||
|
||||
# let todoKeywords = @[
|
||||
# "TODO",
|
||||
# ]
|
||||
# let todoDoneKeywords = @[
|
||||
# "DONE",
|
||||
# ]
|
||||
# let parseHeadingTodo = @[
|
||||
|
||||
# ]
|
||||
|
||||
# let buildHeadingStars =
|
||||
type StringBuilder = BuilderResult[string]
|
||||
type StringBuilderT = string
|
||||
type StringBuilder = Builder[StringBuilderT]
|
||||
type StringBuilderResult = BuilderResult[StringBuilderT]
|
||||
|
||||
let sampleBuilder: StringBuilder = StringBuilder.ok(Builder((
|
||||
parser: initParser(""),
|
||||
tree: newSeq[string](),
|
||||
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 = StringBuilderResult
|
||||
.ok(StringBuilder((
|
||||
parser: initParser("**** Some stars"),
|
||||
tree: newSeq[StringBuilderT](),
|
||||
)))
|
||||
.flatMap((x: StringBuilder) => x.applyParsers(
|
||||
parsers = parseHeadingStars,
|
||||
tokenFoldFn = stringConcat("Stars: ")
|
||||
))
|
||||
.flatMap((x: StringBuilder) => x.applyParsers(
|
||||
parsers = parseHeadingStars,
|
||||
tokenFoldFn = stringConcat("Stars: ")
|
||||
))
|
||||
|
||||
|
||||
echo sampleBuilder
|
||||
# .mapTree((x: string) => x)
|
||||
|
||||
|
||||
# @[
|
||||
|
||||
Reference in New Issue
Block a user