Remove builder from parser type
This commit is contained in:
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user