You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
6.3 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. open import "prelude.ml"
  2. open import "./monads.ml"
  3. private type consumed = C | E
  4. private type error = Unexpected of string * list string
  5. instance show error begin
  6. let show = function
  7. | Unexpected (s, []) -> s
  8. | Unexpected (s, ms) ->
  9. "Unexpected " ^ s ^ "\n"
  10. ^ "Expecting one of " ^ foldl (^) "" ms
  11. end
  12. private type pos <- { line : int, col : int }
  13. private type result 'a =
  14. | Ok of consumed * 'a * string * pos
  15. | Err of consumed * error * string * pos
  16. let join_consumed x y =
  17. match x with
  18. | C -> C
  19. | E -> y
  20. type parser_t 'm 'a = private P of pos -> string -> 'm (result 'a)
  21. type parser <- parser_t identity
  22. instance functor 'm => functor (parser_t 'm) begin
  23. let f <$> P x = P @@ fun pos i ->
  24. flip map (x pos i) @@ fun p ->
  25. match p with
  26. | Ok (c, x, i) -> Ok (c, f x, i)
  27. | Err e -> Err e
  28. end
  29. instance monad 'm => applicative (parser_t 'm) begin
  30. let pure x = P (fun p s -> pure (Ok (E, x, s, p)))
  31. let P f <*> P x = P @@ fun p s ->
  32. let! f = f p s
  33. match f with
  34. | Ok (c, f, s, p) ->
  35. let! x = x p s
  36. match x with
  37. | Ok (c', x, s, p) -> pure @@ Ok (join_consumed c c', f x, s, p)
  38. | Err (c', p) -> pure @@ Err (join_consumed c c', p)
  39. | Err e -> pure @@ Err e
  40. end
  41. let x *> y = (fun _ x -> x) <$> x <*> y
  42. let x <* y = (| const x y |)
  43. let x <$ a = map (const x) a
  44. instance monad 'm => monad (parser_t 'm) begin
  45. let P x >>= f = P @@ fun p s ->
  46. let! x = x p s
  47. match x with
  48. | Ok (c, x, s, p) ->
  49. let P kont = f x
  50. let! x = kont p s
  51. match x with
  52. | Ok (c', x, s) -> pure @@ Ok (join_consumed c c', x, s)
  53. | Err (c', p) -> pure @@ Err (join_consumed c c', p)
  54. | Err e -> pure @@ Err e
  55. end
  56. let private fail e = P (fun p s -> pure (Err (E, e, s, p)))
  57. let empty : forall 'm 'a. monad 'm => parser_t 'm 'a =
  58. fail (Unexpected ("empty parse", []))
  59. let unexpected e =
  60. fail (Unexpected (e, []))
  61. let alt_err (Unexpected (u, xs)) (Unexpected (_, ys)) =
  62. Unexpected (u, xs ++ ys)
  63. let P x <|> P y = P @@ fun p s ->
  64. let! x = x p s
  65. match x with
  66. | Ok x -> pure (Ok x)
  67. | Err (c, m, s, p) ->
  68. let! y = y p s
  69. match y with
  70. | Ok (c', x, s) -> pure (Ok (join_consumed c c', x, s))
  71. | Err (c', m', s) -> pure (Err (join_consumed c c', alt_err m m', s))
  72. let P x <+> y = P @@ fun p s ->
  73. let! x = x p s
  74. match x with
  75. | Ok x -> pure (Ok x)
  76. | Err (c, m, s, p) ->
  77. let P y = force y
  78. let! y = y p s
  79. match y with
  80. | Ok (c', x, s) -> pure (Ok (join_consumed c c', x, s))
  81. | Err (c', m', s) -> pure (Err (join_consumed c c', alt_err m m', s))
  82. private module S = import "lua/string.ml"
  83. let char : forall 'm. applicative 'm => parser_t 'm string =
  84. P @@ fun p s ->
  85. let x = S.substring s 1 1
  86. if x <> "" then
  87. let r = S.substring s 2 (S.length s)
  88. if x == "\n" then
  89. pure @@ Ok (C, x, r, { line = p.line + 1, col = 0 })
  90. else
  91. pure @@ Ok (C, x, r, { line = p.line, col = p.col + 1 })
  92. else
  93. pure @@ Err (E, Unexpected ("end-of-file", ["character"]), s, p)
  94. let eof : forall 'm. applicative 'm => parser_t 'm () =
  95. P @@ fun p s ->
  96. if s == "" then
  97. pure @@ Ok (E, (), s, p)
  98. else
  99. pure @@
  100. Err (E, Unexpected (S.substring s 1 1, ["end-of-file"]), s, p)
  101. let satisfy pred =
  102. P @@ fun p s ->
  103. let x = S.substring s 1 1
  104. if x <> "" && pred x then
  105. let r = S.substring s 2 (S.length s)
  106. if x == "\n" then
  107. pure @@ Ok (C, x, r, { line = p.line + 1, col = 0 })
  108. else
  109. pure @@ Ok (C, x, r, { line = p.line, col = p.col + 1 })
  110. else
  111. let m =
  112. if x == "" then
  113. "end of file"
  114. else
  115. x
  116. pure @@ Err (E, Unexpected (m, ["character"]), s, p)
  117. let P k <?> m = P @@ fun p s ->
  118. let! x = k p s
  119. match x with
  120. | Ok e -> pure (Ok e)
  121. | Err (c, Unexpected (u, _), s) -> pure (Err (c, Unexpected (u, [m]), s))
  122. let many_fold k z (P x) =
  123. let rec go consumed kont pos s =
  124. let! x = x pos s
  125. match x with
  126. | Err ((c, _, s, pos) as p) ->
  127. match c with
  128. | C -> pure (Err p)
  129. | E -> kont consumed z pos s
  130. | Ok (c, x, s, pos) ->
  131. match c with
  132. | E -> error @@ "many: got parser that accepts the empty string"
  133. | C -> go C (fun c -> kont c # k x) pos s
  134. P (go E (fun c z pos s -> pure (Ok (c, z, s, pos))))
  135. let many p = many_fold (::) [] p
  136. let some p =
  137. let! x = p
  138. (x ::) <$> many p
  139. let sep_by_1 sep p =
  140. let! x = p
  141. let! xs = many (sep *> p)
  142. pure (x :: xs)
  143. let sep_by sep p = sep_by_1 sep p <|> pure []
  144. external private val is_infix_of : string -> string -> bool =
  145. "function(s, s2) return s2:find(s) ~= nil end"
  146. external private val is_prefix_of : string -> string -> bool =
  147. "function(s, s2) return (s2:find(s)) == 1 end"
  148. let one_of chs =
  149. let len = S.length chs
  150. let rec loop ch i =
  151. if i > len then
  152. fail @@ Unexpected (ch, ["one of \"" ^ chs ^ "\""])
  153. else if ch == S.substring chs i i then
  154. pure ch
  155. else
  156. loop ch (i + 1)
  157. let! ch = char
  158. loop ch 1
  159. let symbol str =
  160. let len = S.length str
  161. let rec loop acc i =
  162. if i > len then
  163. pure acc
  164. else
  165. let! c = char <?> S.substring str i i
  166. if c == S.substring str i i then
  167. loop (acc ^ c) (i + 1)
  168. else
  169. fail @@ Unexpected (acc ^ c, [S.substring str 1 i])
  170. loop "" 1
  171. let between o c p =
  172. let! _ = o
  173. let! x = p
  174. let! _ = c
  175. pure x
  176. let try (P x) = P @@ fun pos s ->
  177. let! x = x pos s
  178. match x with
  179. | Ok c -> pure (Ok c)
  180. | Err (_, p, _) -> pure (Err (E, p, s, pos))
  181. let optionally p = map Some (try p) <|> pure None
  182. let rec sep_end_by_1 sep p =
  183. let! x = p
  184. ( let! _ = sep
  185. let! xs = sep_end_by sep p
  186. pure (x :: xs)
  187. ) <|> pure [x]
  188. and sep_end_by sep p =
  189. sep_end_by_1 sep p <|> pure []
  190. let chainr1 p op =
  191. let rec scan =
  192. let! x = p
  193. rest x
  194. and rest x =
  195. ( let! f = op
  196. let! y = scan
  197. pure (f x y)
  198. ) <|> pure x
  199. let _ = rest (* shut up, amc *)
  200. scan
  201. let parse (P x) s =
  202. let! x = x { line = 0, col = 0 } s
  203. match x with
  204. | Ok (_, x, r) -> pure @@ Right (x, r)
  205. | Err (_, m, _, p) -> pure @@ Left (m, p)
  206. let run_parser p s =
  207. let Id x = parse p s
  208. x
  209. let run_parser' (P x) s =
  210. let Id x = x { line = 0, col = 0 } s
  211. x
  212. let lift m = P @@ fun pos s ->
  213. let! x = m
  214. pure @@ Ok (E, x, s, pos)
  215. let morph (k : forall 'a. 'm 'a -> 'n 'a) (P x) = P @@ fun s -> k (x s)
  216. let void x = map (const ()) x