Remove builder from parser type
This commit is contained in:
@@ -47,19 +47,6 @@ type
|
|||||||
parser*: Parser
|
parser*: Parser
|
||||||
ParserResult* = Result[Parser, ParserError]
|
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
|
# -- Initalizers
|
||||||
|
|
||||||
func initParserToken*(x: char): ParserToken = ParserToken(kind: parserTokenChar, charValue: x)
|
func initParserToken*(x: char): ParserToken = ParserToken(kind: parserTokenChar, charValue: x)
|
||||||
@@ -78,12 +65,6 @@ func initParser*(str: string): Parser =
|
|||||||
func initParserResult*(str: string): ParserResult =
|
func initParserResult*(str: string): ParserResult =
|
||||||
ParserResult.ok(initParser(str))
|
ParserResult.ok(initParser(str))
|
||||||
|
|
||||||
func initBuilder*[T](t: Builder[T], parser: Parser, tree: seq[T]): Builder[T] =
|
|
||||||
Builder[T]((
|
|
||||||
parser,
|
|
||||||
tree
|
|
||||||
))
|
|
||||||
|
|
||||||
# -- Getters
|
# -- Getters
|
||||||
|
|
||||||
func tokenStringValue*(x: ParserToken): string =
|
func tokenStringValue*(x: ParserToken): string =
|
||||||
@@ -97,7 +78,6 @@ func tokenStringValue*(x: ParserToken): string =
|
|||||||
func tokensToString*(tokens: seq[ParserToken]): string =
|
func tokensToString*(tokens: seq[ParserToken]): string =
|
||||||
tokens.foldl(a & b.tokenStringValue(), "")
|
tokens.foldl(a & b.tokenStringValue(), "")
|
||||||
|
|
||||||
|
|
||||||
# -- Modifiers
|
# -- Modifiers
|
||||||
|
|
||||||
func flattenParserTokens*(parser: Parser): ParserResult =
|
func flattenParserTokens*(parser: Parser): ParserResult =
|
||||||
@@ -145,201 +125,6 @@ func setErrorExpectedField*(err: ParserError, expected: string): ParserError =
|
|||||||
parser: err.parser,
|
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
|
# -- Stringifiers
|
||||||
|
|
||||||
func pprint*(x: ParserToken): string =
|
func pprint*(x: ParserToken): string =
|
||||||
|
|||||||
Reference in New Issue
Block a user