-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparsec.ml
61 lines (46 loc) · 1.13 KB
/
parsec.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
type 'a stream = 'a LazyStream.t
type ('t, 'a) reply =
Fail
| Match of 'a
| Parse of ('t, 'a) parser * 't stream
and ('t, 'a) parser =
't stream -> ('t, 'a) reply
let return x _ = Match x
let rec bind p f s =
match p s with
| Fail -> Fail
| Match x -> f x s
| Parse (q, s') -> Parse (bind q f, s')
let choose p q s =
match p s with
| Fail -> q s
| r -> r
let rec attempt p s =
match p s with
| Parse (q', s') -> attempt q' s'
| r -> r
let rec run p s =
match p s with
| Fail -> None
| Match r -> Some r
| Parse (q, s') -> run q s'
let token (f : 'a -> 'b option) : ('a, 'b) parser = fun s ->
match LazyStream.next s with
| None -> Fail
| Some (t, s') ->
match f t with
| None -> Fail
| Some x -> Parse (return x, s')
let ( >>= ) = bind
let ( <|> ) = choose
let rec fold1 f z p =
p >>= fun x ->
fold f (f z x) p
and fold f z p =
fold1 f z p <|> return z
let rec many1 p =
p >>= fun x ->
many p >>= fun xs ->
return (x :: xs)
and many p =
many1 p <|> return []