Remove builder from parser type

This commit is contained in:
Florian Schroedl
2022-08-26 18:55:51 +02:00
parent ef2fbb9a16
commit 7d2c45786f

View File

@@ -47,19 +47,6 @@ type
parser*: Parser
ParserResult* = Result[Parser, ParserError]
Builder*[T] = tuple[
parser: Parser,
tree: seq[T]
]
BuilderResult*[T] = Result[Builder[T], (Builder[T], string)]
# SingleBuilder*[T] = tuple[
# parser: Parser,
# tree: T
# ]
# SingleBuilderResult*[T] = Result[SingleBuilder[T], (SingleBuilder[T], string)]
# -- Initalizers
func initParserToken*(x: char): ParserToken = ParserToken(kind: parserTokenChar, charValue: x)
@@ -78,12 +65,6 @@ func initParser*(str: string): Parser =
func initParserResult*(str: string): ParserResult =
ParserResult.ok(initParser(str))
func initBuilder*[T](t: Builder[T], parser: Parser, tree: seq[T]): Builder[T] =
Builder[T]((
parser,
tree
))
# -- Getters
func tokenStringValue*(x: ParserToken): string =
@@ -97,7 +78,6 @@ func tokenStringValue*(x: ParserToken): string =
func tokensToString*(tokens: seq[ParserToken]): string =
tokens.foldl(a & b.tokenStringValue(), "")
# -- Modifiers
func flattenParserTokens*(parser: Parser): ParserResult =
@@ -145,201 +125,6 @@ func setErrorExpectedField*(err: ParserError, expected: string): ParserError =
parser: err.parser,
)
func mapTree*[T](builder: BuilderResult[T], fn: seq[T] -> seq[T]): BuilderResult[T] =
builder.map(func(b: Builder[T]): Builder[T] = Builder((
parser: b[0],
tree: fn(b[1]),
)))
func tryParser*[T](
builder: Builder[T],
parser: Parser -> ParserResult,
): BuilderResult[T] =
## Try out a `parser` on a `builder`
## When succesful return the original builder, otherwise return an error
ParserResult.ok(Parser(
state: builder[0].state,
tokens: @[]
))
.flatMap(parser)
.foldTokens(
(err: ParserError) => BuilderResult[T].err((builder, "Error")),
(newTokens: seq[ParserToken]) => BuilderResult[T].ok(builder),
)
func tryParser*[T](
builder: BuilderResult[T],
parser: Parser -> ParserResult,
): BuilderResult[T] =
## Try out a `parser` on a `builder` result
## When succesful return the ok builder, otherwise return an error
builder.flatMap((x: Builder[T]) => tryParser(x, parser))
func applyParsersToSingle*[T](
builder: Builder[T],
parsers: seq[Parser -> ParserResult],
tokenFoldFn: (seq[ParserToken], T) -> T,
optional = false,
initT: T,
isFirst: bool,
): BuilderResult[T] =
# Apply the current parsing functions and convert to text tokens wrapped in ParserResult
let newParser = ParserResult.ok(Parser(
state: builder[0].state,
tokens: @[]
))
.parseSeq(parsers)
newParser
.foldTokens(
(err: ParserError) => BuilderResult[T].err((builder, "foo")),
(newTokens: seq[ParserToken]) => (
if optional and newTokens.len == 0:
BuilderResult[T].ok(builder)
else:
BuilderResult[T].ok(
builder.initBuilder(
newParser.unsafeGet(),
builder.tree
.last()
.filter(x => not isFirst)
.orElse(just(initT))
.map((x: T) => @[tokenFoldFn(newTokens, x)])
.getOrElse(newSeq[T]())
)
)
)
)
## TODO Implement applyParsersSeqToSingle with this function by forming the concatFn
func applyParsersToSeq*[T](
builder: Builder[T],
parsers: seq[Parser -> ParserResult],
tokenFoldFn: (seq[ParserToken], T) -> T,
# concatFn = `&`,
optional = false,
isFirst: bool,
): BuilderResult[T] =
# Apply the current parsing functions and convert to text tokens wrapped in ParserResult
let newParser = ParserResult.ok(Parser(
state: builder[0].state,
tokens: @[]
))
.parseSeq(parsers)
newParser
.foldTokens(
(err: ParserError) => BuilderResult[T].err((builder, "foo")),
(newTokens: seq[ParserToken]) => (
if optional and newTokens.len == 0:
BuilderResult[T].ok(builder)
else:
BuilderResult[T].ok(
builder.initBuilder(
newParser.unsafeGet(),
builder.tree & builder.tree
)
)
)
)
func applyParsersSeqToSingle*[T](
builderResult: BuilderResult[T],
initT: T,
xs: seq[tuple[
parsers: seq[Parser -> ParserResult],
tokenFoldFn: (seq[ParserToken], T) -> T,
ignoreEmpty: bool,
]],
): BuilderResult[T] =
xs.foldl(
a.flatMap((builder: Builder[T]) => applyParsersToSingle(
builder = builder,
parsers = b.parsers,
tokenFoldFn = b.tokenFoldFn,
optional = b.ignoreEmpty,
initT = initT,
isFirst = a == builderResult
)),
builderResult
)
func applyParsersSeqToSeq*[T](
builderResult: BuilderResult[T],
xs: seq[tuple[
parsers: seq[Parser -> ParserResult],
tokenFoldFn: (seq[ParserToken], T) -> T,
ignoreEmpty: bool,
# concatFn: (seq[T], seq[T]) -> seq[T],
]],
): BuilderResult[T] =
xs.foldl(
a.flatMap((builder: Builder[T]) => applyParsersToSeq(
builder = builder,
parsers = b.parsers,
tokenFoldFn = b.tokenFoldFn,
optional = b.ignoreEmpty,
isFirst = a == builderResult,
# concatFn = concatFn
)),
builderResult
)
func applyParsers*[T](
builder: Builder[T],
parsers: seq[Parser -> ParserResult],
tokenFoldFn: (seq[ParserToken], seq[T]) -> seq[T],
): BuilderResult[T] =
# func nested(b: Builder[T]): BuilderResult[T] =
let newParser = ParserResult.ok(Parser(
state: builder[0].state,
tokens: @[]
))
.parseSeq(parsers)
newParser
.foldTokens(
(err: ParserError) => BuilderResult[T].err((builder, "foo")),
(newTokens: seq[ParserToken]) => BuilderResult[T].ok(
builder.initBuilder(newParser.unsafeGet(), tokenFoldFn(newTokens, builder[1]))
),
)
func applyParsersSeq*[T](
builder: BuilderResult[T],
xs: seq[tuple[
parsers: seq[Parser -> ParserResult],
tokenFoldFn: (seq[ParserToken], seq[T]) -> seq[T],
]]): BuilderResult[T] =
xs.foldl(a.flatMap((x: Builder[T]) => x.applyParsers(b[0], b[1])), builder)
func foldBuilder*[T, T2](
builderResult: BuilderResult[T],
onError: string -> T2,
onSuccess: seq[T] -> T2,
): T =
if builderResult.isOk():
onSuccess(builderResult.unsafeGet().tree)
else:
let err = builderResult.error()
onError(err[1])
# func parseBuildOr*[T](
# ## Checks
# builderResult: BuilderResult[T],
# builders: seq[tuple[
# parsers: seq[Parser -> ParserResult],
# tokenFoldFn: (seq[ParserToken], T) -> T,
# ]],
# defaultBuilder: tuple[
# defaultParser: Parser -> ParserResult,
# defaultFoldFn: (seq[ParserToken], T) -> T,
# ],
# until:
# ): BuilderResult[T] =
# -- Stringifiers
func pprint*(x: ParserToken): string =