Add ignore function
This commit is contained in:
49
src/test.nim
49
src/test.nim
@@ -61,7 +61,7 @@ proc initParser(str: string): ParserResult =
|
|||||||
Parser(
|
Parser(
|
||||||
state: ParserState(
|
state: ParserState(
|
||||||
stream: str,
|
stream: str,
|
||||||
position: 0,
|
position: -1,
|
||||||
lastPosition: 0,
|
lastPosition: 0,
|
||||||
),
|
),
|
||||||
tokens: newSeq[Token](),
|
tokens: newSeq[Token](),
|
||||||
@@ -70,32 +70,65 @@ proc initParser(str: string): ParserResult =
|
|||||||
func ch(c1: char): (Parser -> ParserResult) {.inline.} =
|
func ch(c1: char): (Parser -> ParserResult) {.inline.} =
|
||||||
return func(parser: Parser): ParserResult =
|
return func(parser: Parser): ParserResult =
|
||||||
let state = parser.state
|
let state = parser.state
|
||||||
let c2 = state.stream[state.position]
|
let newIndex = state.position + 1
|
||||||
|
|
||||||
|
if newIndex > (state.stream.len - 1):
|
||||||
|
return err((parser, &"Expected {c1} at {newIndex}, got End of string"))
|
||||||
|
else:
|
||||||
|
let c2 = state.stream[newIndex]
|
||||||
|
|
||||||
if c1 == c2:
|
if c1 == c2:
|
||||||
return Parser(
|
return Parser(
|
||||||
state: ParserState(
|
state: ParserState(
|
||||||
stream: state.stream,
|
stream: state.stream,
|
||||||
position: state.lastPosition + 1,
|
position: newIndex,
|
||||||
lastPosition: parser.state.position,
|
lastPosition: parser.state.position,
|
||||||
),
|
),
|
||||||
tokens: parser.tokens & Token(value: c2)
|
tokens: parser.tokens & Token(value: c2)
|
||||||
).ok()
|
).ok()
|
||||||
else:
|
else:
|
||||||
return err((parser, &"Expected {c2} at {state.lastPosition}, got {c1}"))
|
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 =
|
proc parseSeq(parser: ParserResult, xs: seq[Parser -> ParserResult]): ParserResult =
|
||||||
xs.foldl(a.flatMap(b), parser)
|
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]
|
# type R = Result[int, string]
|
||||||
|
|
||||||
# echo R.ok 4
|
# echo R.ok 4
|
||||||
|
|
||||||
let fooParser = initParser("FOO").parseSeq(@[
|
# let i = 3
|
||||||
ch('F'),
|
|
||||||
ch('O'),
|
# echo $("FOO"[i])
|
||||||
ch('O'),
|
|
||||||
|
let fooParser = initParser("FOO_BAR").parseSeq(@[
|
||||||
|
str("FOO"),
|
||||||
|
ignore(ch('_')),
|
||||||
|
ignore(ch('_')),
|
||||||
|
ignore(ch('_')),
|
||||||
|
ignore(ch('_')),
|
||||||
|
ch('B'),
|
||||||
|
ch('A'),
|
||||||
|
ch('R'),
|
||||||
])
|
])
|
||||||
|
|
||||||
echo fooParser
|
echo fooParser
|
||||||
|
|||||||
Reference in New Issue
Block a user