parsecomb.nim 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. type Input[T] = object
  2. toks: seq[T]
  3. index: int
  4. type
  5. ResultKind* = enum rkSuccess, rkFailure
  6. Result*[T, O] = object
  7. case kind*: ResultKind
  8. of rkSuccess:
  9. output*: O
  10. input: Input[T]
  11. of rkFailure:
  12. nil
  13. type
  14. Parser*[T, O] = proc (input: Input[T]): Result[T, O]
  15. proc unit*[T, O](v: O): Parser[T, O] =
  16. result = proc (inp: Input[T]): Result[T, O] =
  17. Result[T, O](kind: rkSuccess, output: v, input: inp)
  18. proc fail*[T, O](): Parser[T, O] =
  19. result = proc (inp: Input[T]): Result[T, O] =
  20. Result(kind: rkFailure)
  21. method runInput[T, O](self: Parser[T, O], inp: Input[T]): Result[T, O] =
  22. # hmmm ..
  23. type tmp = proc (input: Input[T]): Result[T, O]
  24. # XXX: above needed for now, as without the `tmp` bit below, it compiles to invalid C.
  25. tmp(self)(inp)
  26. proc run*[T, O](self: Parser[T, O], toks: seq[T]): Result[T, O] =
  27. self.runInput(Input[T](toks: toks, index: 0))
  28. proc chain*[T, O1, O2](self: Parser[T, O1], nextp: proc (v: O1): Parser[T, O2]): Parser[T, O2] =
  29. result = proc (inp: Input[T]): Result[T, O2] =
  30. let r = self.runInput(inp)
  31. case r.kind:
  32. of rkSuccess:
  33. nextp(r.output).runInput(r.input)
  34. of rkFailure:
  35. Result[T, O2](kind: rkFailure)
  36. method skip[T](self: Input[T], n: int): Input[T] {.base.} =
  37. Input[T](toks: self.toks, index: self.index + n)
  38. proc pskip*[T](n: int): Parser[T, tuple[]] =
  39. result = proc (inp: Input[T]): Result[T, tuple[]] =
  40. if inp.index + n <= inp.toks.len:
  41. Result[T, tuple[]](kind: rkSuccess, output: (), input: inp.skip(n))
  42. else:
  43. Result[T, tuple[]](kind: rkFailure)
  44. proc tok*[T](t: T): Parser[T, T] =
  45. result = proc (inp: Input[T]): Result[T, T] =
  46. if inp.index < inp.toks.len and inp.toks[inp.index] == t:
  47. pskip[T](1).then(unit[T, T](t)).runInput(inp)
  48. else:
  49. Result[T, T](kind: rkFailure)
  50. proc `+`*[T, O](first: Parser[T, O], second: Parser[T, O]): Parser[T, O] =
  51. result = proc (inp: Input[T]): Result[T, O] =
  52. let r = first.runInput(inp)
  53. case r.kind
  54. of rkSuccess:
  55. r
  56. else:
  57. second.runInput(inp)
  58. # end of primitives (definitions involving Parser(..))
  59. proc map*[T, O1, O2](self: Parser[T, O1], p: proc (v: O1): O2): Parser[T, O2] =
  60. self.chain(proc (v: O1): Parser[T, O2] =
  61. unit[T, O2](p(v)))
  62. proc then*[T, O1, O2](self: Parser[T, O1], next: Parser[T, O2]): Parser[T, O2] =
  63. self.chain(proc (v: O1): Parser[T, O2] =
  64. next)
  65. proc `*`*[T, O1, O2](first: Parser[T, O1], second: Parser[T, O2]): Parser[T, (O1, O2)] =
  66. first.chain(proc (v1: O1): Parser[T, (O1, O2)] =
  67. second.map(proc (v2: O2): (O1, O2) =
  68. (v1, v2)))
  69. proc repeat0*[T, O](inner: Parser[T, O]): Parser[T, seq[O]] =
  70. var nothing = unit[T, seq[O]](@[])
  71. inner.chain(proc(v: O): Parser[T, seq[O]] =
  72. repeat0(inner).map(proc(vs: seq[O]): seq[O] =
  73. @[v] & vs)) + nothing
  74. proc repeat1*[T, O](inner: Parser[T, O]): Parser[T, seq[O]] =
  75. inner.chain(proc(v: O): Parser[T, seq[O]] =
  76. repeat0(inner).map(proc(vs: seq[O]): seq[O] =
  77. @[v] & vs))
  78. proc leftRec*[T, O, A](inner: Parser[T, O], after: Parser[T, A], fold: proc(i: O, a: A): O): Parser[T, O] =
  79. (inner*repeat0(after)).map(proc(ias: (O, seq[A])): O =
  80. var (i, asx) = ias
  81. for a in asx:
  82. i = fold(i, a)
  83. i)
  84. proc lazy*[T, O](inner: proc(): Parser[T, O]): Parser[T, O] =
  85. unit[T, tuple[]](()).chain(proc(v: tuple[]): Parser[T, O] =
  86. inner())