add parser combinator test; uses multiple tuples/generics features
This commit is contained in:
parent
7527da7043
commit
3dcec39739
2 changed files with 160 additions and 0 deletions
55
tests/misc/tparsecombnum.nim
Normal file
55
tests/misc/tparsecombnum.nim
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import parsecomb
|
||||
|
||||
discard """
|
||||
output: "-289096"
|
||||
"""
|
||||
|
||||
type Num = int
|
||||
|
||||
# forward stuff
|
||||
var exp3: Parser[string, Num]
|
||||
var exp = lazy(proc(): Parser[string, Num] = exp3)
|
||||
|
||||
var digit = (proc(): Parser[string, Num] =
|
||||
result = tok("0").then(unit[string, Num](Num(0)))
|
||||
for n in 1..9:
|
||||
result = result + tok($n).then(unit[string, Num](Num(n)))
|
||||
)()
|
||||
|
||||
var num = repeat1(digit).map(proc(ds: seq[Num]): Num =
|
||||
result = 0
|
||||
for d in ds:
|
||||
result = result*10 + d)
|
||||
|
||||
type Op = proc(a, b: Num): Num
|
||||
|
||||
var plusOp = tok("+").then(unit[string, Op](proc(a, b: Num): Num = a + b))
|
||||
var minusOp = tok("-").then(unit[string, Op](proc(a, b: Num): Num = a - b))
|
||||
var timesOp = tok("*").then(unit[string, Op](proc(a, b: Num): Num = a*b))
|
||||
var divideOp = tok("/").then(unit[string, Op](proc(a, b: Num): Num = a div b))
|
||||
|
||||
var paren = (tok("(") * exp * tok(")")).map(proc(ler: ((string, Num), string)): Num =
|
||||
var (le, r) = ler
|
||||
var (l, e) = le
|
||||
e)
|
||||
|
||||
proc foldOp(a: Num, ob: (Op, Num)): Num =
|
||||
var (o, b) = ob
|
||||
o(a, b)
|
||||
|
||||
var exp0 = paren + num
|
||||
var exp1 = exp0.leftRec((timesOp + divideOp)*exp0, foldOp)
|
||||
var exp2 = exp1.leftRec((plusOp + minusOp)*exp1, foldOp)
|
||||
exp3 = exp2
|
||||
|
||||
proc strsplit(s: string): seq[string] =
|
||||
result = @[]
|
||||
for i in 0 .. s.len - 1:
|
||||
result.add($s[i])
|
||||
|
||||
var r = exp.run("523-(1243+411/744*1642/1323)*233".strsplit)
|
||||
case r.kind:
|
||||
of rkSuccess:
|
||||
echo r.output
|
||||
of rkFailure:
|
||||
echo "failed"
|
||||
Loading…
Add table
Add a link
Reference in a new issue