Parser transformation
This commit is contained in:
102
src/test.nim
102
src/test.nim
@@ -37,7 +37,7 @@ type
|
|||||||
ParserResult* = Result[Parser, ParserError]
|
ParserResult* = Result[Parser, ParserError]
|
||||||
|
|
||||||
Builder*[T] = tuple[
|
Builder*[T] = tuple[
|
||||||
parser: ParserResult,
|
parser: Parser,
|
||||||
tree: seq[T]
|
tree: seq[T]
|
||||||
]
|
]
|
||||||
BuilderResult*[T] = Result[Builder[T], (Builder[T], string)]
|
BuilderResult*[T] = Result[Builder[T], (Builder[T], string)]
|
||||||
@@ -109,7 +109,7 @@ proc `$`*(x: ParserError): string =
|
|||||||
{errSpace}^ Expected '{expected}' but got '{unexpected}'"""
|
{errSpace}^ Expected '{expected}' but got '{unexpected}'"""
|
||||||
else: "ParseError"
|
else: "ParseError"
|
||||||
|
|
||||||
proc initParser(str: string): ParserResult =
|
proc initParser(str: string): Parser =
|
||||||
Parser(
|
Parser(
|
||||||
state: ParserState(
|
state: ParserState(
|
||||||
stream: str,
|
stream: str,
|
||||||
@@ -117,7 +117,7 @@ proc initParser(str: string): ParserResult =
|
|||||||
lastPosition: 0,
|
lastPosition: 0,
|
||||||
),
|
),
|
||||||
tokens: newSeq[Token](),
|
tokens: newSeq[Token](),
|
||||||
).ok()
|
)
|
||||||
|
|
||||||
func ch(expectedChars: set[char]): (Parser -> ParserResult) {.inline.} =
|
func ch(expectedChars: set[char]): (Parser -> ParserResult) {.inline.} =
|
||||||
return func(parser: Parser): ParserResult =
|
return func(parser: Parser): ParserResult =
|
||||||
@@ -262,67 +262,71 @@ proc foldTokens[T](
|
|||||||
let err = parserResult.error()
|
let err = parserResult.error()
|
||||||
onError(err)
|
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]) =
|
proc applyParsers[T](
|
||||||
# builder.map(proc(b: Builder) =
|
builder: Builder[T],
|
||||||
# (@parser, @builder) := builder
|
parsers: seq[Parser -> ParserResult],
|
||||||
# b
|
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 =
|
newParser
|
||||||
# (@parser, @builder) := builder
|
.foldTokens(
|
||||||
# parser.foldTokens(
|
(err: ParserError) => BuilderResult[T].err((builder, "foo")),
|
||||||
# proc(x: ParserError): BuilderResult = err(x),
|
(newTokens: seq[Token]) => BuilderResult[T].ok(
|
||||||
# proc(xs: seq[Token]): BuilderResult = ok(parser, builder.map()),
|
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:
|
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 = @[
|
let parseHeadingStars = @[
|
||||||
manyUntil(ch('*'), ch(' ')),
|
manyUntil(ch('*'), ch(' ')),
|
||||||
ignore(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 =
|
# let buildHeadingStars =
|
||||||
type StringBuilder = BuilderResult[string]
|
type StringBuilderT = string
|
||||||
|
type StringBuilder = Builder[StringBuilderT]
|
||||||
|
type StringBuilderResult = BuilderResult[StringBuilderT]
|
||||||
|
|
||||||
let sampleBuilder: StringBuilder = StringBuilder.ok(Builder((
|
proc stringConcat(typeInfo: StringBuilderT):
|
||||||
parser: initParser(""),
|
(seq[Token], seq[StringBuilderT]) -> seq[StringBuilderT] =
|
||||||
tree: newSeq[string](),
|
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
|
echo sampleBuilder
|
||||||
# .mapTree((x: string) => x)
|
|
||||||
|
|
||||||
|
|
||||||
# @[
|
# @[
|
||||||
|
|||||||
Reference in New Issue
Block a user