Add ignore function
This commit is contained in:
65
src/test.nim
65
src/test.nim
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user