Add ignore function

This commit is contained in:
Florian Schroedl
2022-01-20 17:00:00 +01:00
parent b7d4951549
commit 987f78812c

View File

@@ -61,7 +61,7 @@ proc initParser(str: string): ParserResult =
Parser(
state: ParserState(
stream: str,
position: 0,
position: -1,
lastPosition: 0,
),
tokens: newSeq[Token](),
@@ -70,32 +70,65 @@ proc initParser(str: string): ParserResult =
func ch(c1: char): (Parser -> ParserResult) {.inline.} =
return func(parser: Parser): ParserResult =
let state = parser.state
let c2 = state.stream[state.position]
let newIndex = state.position + 1
if c1 == c2:
return Parser(
state: ParserState(
stream: state.stream,
position: state.lastPosition + 1,
lastPosition: parser.state.position,
),
tokens: parser.tokens & Token(value: c2)
).ok()
if newIndex > (state.stream.len - 1):
return err((parser, &"Expected {c1} at {newIndex}, got End of string"))
else:
return err((parser, &"Expected {c2} at {state.lastPosition}, got {c1}"))
let c2 = state.stream[newIndex]
if c1 == c2:
return Parser(
state: ParserState(
stream: state.stream,
position: newIndex,
lastPosition: parser.state.position,
),
tokens: parser.tokens & Token(value: c2)
).ok()
else:
return err((parser, &"Expected {c2} at {newIndex}, got {c1}"))
func ignore(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
## Parse characters but throw success tokens away
return proc(parser: Parser): ParserResult =
return parserFn(parser)
.map((x: Parser) => Parser(
state: x.state,
tokens: parser.tokens,
))
proc parseSeq(parser: ParserResult, xs: seq[Parser -> ParserResult]): ParserResult =
xs.foldl(a.flatMap(b), parser)
func str(s: string): (Parser -> ParserResult) {.inline.} =
return func(parser: Parser): ParserResult =
var p = parser.ok()
for c in s.items:
p = p.flatMap(ch(c))
return p
# func str(s1: string): (Parser -> ParserResult) {.inline.} =
# return func(parser: Parser): ParserResult =
# return parser.flatMap(x => parseSeq(@[ch('F')]))
# type R = Result[int, string]
# echo R.ok 4
let fooParser = initParser("FOO").parseSeq(@[
ch('F'),
ch('O'),
ch('O'),
# let i = 3
# echo $("FOO"[i])
let fooParser = initParser("FOO_BAR").parseSeq(@[
str("FOO"),
ignore(ch('_')),
ignore(ch('_')),
ignore(ch('_')),
ignore(ch('_')),
ch('B'),
ch('A'),
ch('R'),
])
echo fooParser