OSDN Git Service

4cbecc4d730e107f92a146ed1bb3709167027a5d
[happyabc/happyabc.git] / src / parsec.ml
1 open Base
2
3 let fail () =
4   raise Stream.Failure
5
6 let rec times f =
7   function
8       0 -> ()
9     | n -> f () ;times f (n-1)
10
11 let rec repeat n f stream =
12   if n = 0 then
13     []
14   else
15     match stream with parser
16         [<c = f>] ->
17           c::repeat (n-1) f stream
18       | [<>] ->
19           raise (Stream.Error "invalid format")
20
21 let repeat_l n f stream =
22   repeat (Int32.to_int n) f stream
23
24 let string str stream = 
25   let cs =
26     ExtString.String.explode str in
27   let n = 
28     List.length cs in
29     match Stream.npeek n stream with
30         ys when cs = ys ->
31           times (fun ()->Stream.junk stream) n;
32           ys
33       | _ ->
34           fail ()
35
36 let char c stream =
37   match Stream.peek stream with
38       Some x when x = c ->
39         Stream.junk stream;
40         x
41     | _ ->
42         fail ()
43
44 let rec until c stream =
45   match Stream.peek stream with
46       Some x when x != c ->
47         Stream.junk stream;
48         x::(until c stream)
49     | _ ->
50         []
51
52 let one_of str stream =
53   match Stream.peek stream with
54       Some c when String.contains str c ->
55         Stream.next stream
56     | _ ->
57         fail ()
58
59 let option f stream =
60   try
61     Some (f stream)
62   with Stream.Failure ->
63     None
64
65 let (<|>) f g = 
66   parser 
67       [<e = f>] -> e
68     | [<e = g>] -> e
69
70 let rec many parse stream = 
71   match stream with parser
72       [< e = parse; s>] -> e::many parse s
73     | [<>] -> []
74
75 let many1 parse stream =
76   let x =
77     parse stream in
78     x::many parse stream
79
80 let alpha stream = 
81   match Stream.peek stream with
82       Some ('a'..'z') | Some ('A'..'Z') ->
83         Stream.next stream
84     | _ ->
85         fail ()
86
87 let digit stream =
88   match Stream.peek stream with
89       Some ('0'..'9') ->
90         Stream.next stream
91     | _ ->
92         fail ()
93
94 let try_ f stream =
95   (* 
96      Use black-magic to save stream state
97      
98      from stream.ml:
99      type 'a t = { count : int; data : 'a data }
100   *)
101   let t =
102     Obj.repr stream in
103   let count =
104     Obj.field t 0 in
105   let data =
106     Obj.field t 1 in
107     try
108       f stream
109     with Stream.Failure | Stream.Error _ ->
110       Obj.set_field t 0 count;
111       Obj.set_field t 1 data;
112       fail ()
113
114 module N = Node
115 module Node = struct
116   let string str stream =
117     let n =
118       String.length str in
119     let xs =
120       ExtString.String.implode @@ 
121         List.map N.value @@ 
122         Stream.npeek n stream in
123       if xs = str then 
124         (times (fun ()->Stream.junk stream) n;
125          xs)
126       else
127         fail ()
128 end