/[svn]/cduce/trunk/parser/parser.ml
ViewVC logotype

Contents of /cduce/trunk/parser/parser.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 133 - (show annotations)
Tue Jul 10 17:09:20 2007 UTC (5 years, 10 months ago) by abate
Original Path: parser/parser.ml
File size: 10986 byte(s)
[r2002-11-16 14:34:49 by cvscast] Empty log message

Original author: cvscast
Date: 2002-11-16 14:35:45+00:00
1 open Location
2 open Ast
3
4 (* let () = Grammar.error_verbose := true *)
5
6 let gram = Grammar.gcreate (Wlexer.lexer Wlexer.token Wlexer.latin1_engine)
7
8
9 let prog = Grammar.Entry.create gram "prog"
10 let expr = Grammar.Entry.create gram "expression"
11 let pat = Grammar.Entry.create gram "type/pattern expression"
12 let regexp = Grammar.Entry.create gram "type/pattern regexp"
13 let const = Grammar.Entry.create gram "scalar constant"
14
15 let rec multi_prod loc = function
16 | [ x ] -> x
17 | x :: l -> mk loc (Prod (x, multi_prod loc l))
18 | [] -> assert false
19
20 let rec tuple loc = function
21 | [ x ] -> x
22 | x :: l -> mk loc (Pair (x, tuple loc l))
23 | [] -> assert false
24
25 let tuple_queue =
26 List.fold_right (fun x q -> mk x.loc (Pair (x, q)))
27
28 let char = mk noloc (Internal (Types.char Chars.any))
29 let string_regexp = Star (Elem char)
30
31 let cst_nil = mk noloc (Cst (Types.Atom Sequence.nil_atom))
32
33 let seq_of_string pos s =
34 let (pos,_) = pos in
35 let rec aux accu i =
36 if (i = 0)
37 then accu
38 else aux (((pos+i,pos+i+1),s.[i-1])::accu) (i-1) in
39 aux [] (String.length s)
40
41 exception Error of string
42 let error loc s = raise (Location (loc, Error s))
43
44 let parse_char loc s =
45 (* TODO: Unicode *)
46 if String.length s <> 1 then
47 error loc "Character litteral must have length 1";
48 s.[0]
49
50 let char_list pos s =
51 let s = seq_of_string pos s in
52 List.map (fun (loc,c) -> mk loc (Cst (Types.Char (Chars.Unichar.from_char c)))) s
53
54
55 EXTEND
56 GLOBAL: prog expr pat regexp const;
57
58 prog: [
59 [ l = LIST0 [ p = phrase; ";;" -> mk loc p ]; EOI -> l ]
60 ];
61
62 phrase: [
63 [ (p,e) = let_binding -> LetDecl (p,e)
64 | (p,e1) = let_binding; "in"; e2 = expr LEVEL "top"->
65 EvalStatement (mk loc (Match (e1,[p,e2])))
66 | LIDENT "type"; x = UIDENT; "="; t = pat -> TypeDecl (x,t)
67 | LIDENT "debug"; d = debug_directive -> Debug d
68 ] |
69 [ e = expr -> EvalStatement e
70 ]
71 ];
72
73 debug_directive: [
74 [ LIDENT "filter"; t = pat; p = pat -> `Filter(t,p)
75 | LIDENT "accept"; p = pat -> `Accept p
76 | LIDENT "compile"; t = pat; p = LIST1 pat -> `Compile (t,p)
77 | LIDENT "normal_record"; t = pat -> `Normal_record t
78 ]
79 ];
80
81 expr: [
82 "top" RIGHTA
83 [ "match"; e = SELF; "with"; b = branches -> mk loc (Match (e,b))
84 | "try"; e = SELF; "with"; b = branches ->
85 let default =
86 (mk noloc (Capture "x"),
87 mk noloc (Op ("raise",[mk noloc (Var "x")]))) in
88 mk loc (Try (e,b@[default]))
89 | "map"; e = SELF; "with"; b = branches -> mk loc (Map (e,b))
90 | "transform"; e = SELF; "with"; b = branches ->
91 let default = mk noloc (Capture "x"), cst_nil in
92 mk loc (Op ("flatten", [mk loc (Map (e,b@[default]))]))
93 | "fun"; (f,a,b) = fun_decl ->
94 mk loc (Abstraction { fun_name = f; fun_iface = a; fun_body = b })
95 | (p,e1) = let_binding; "in"; e2 = expr LEVEL "top"->
96 mk loc (Match (e1,[p,e2]))
97 | e = expr; ":"; p = pat ->
98 mk loc (Forget (e,p))
99 ]
100
101
102 |
103 [ e1 = expr; op = ["+" | "-" | "@"]; e2 = expr -> mk loc (Op (op,[e1;e2]))
104 ]
105 |
106 [ e1 = expr; op = ["*" | "/"]; e2 = expr -> mk loc (Op (op,[e1;e2]))
107 ]
108 |
109 [ e = expr; "."; l = [LIDENT | UIDENT] ->
110 mk loc (Dot (e,Types.LabelPool.mk l))
111 ]
112
113 |
114 [ op = [ LIDENT "flatten"
115 | LIDENT "load_xml"
116 | LIDENT "print_xml"
117 | LIDENT "print"
118 | LIDENT "raise"
119 | LIDENT "int_of"
120 | LIDENT "string_of"
121 ];
122 e = expr -> mk loc (Op (op,[e]))
123 | op = [ LIDENT "dump_to_file" ];
124 e1 = expr LEVEL "no_appl"; e2 = expr -> mk loc (Op (op, [e1;e2]))
125 | e1 = expr; e2 = expr -> mk loc (Apply (e1,e2))
126 ]
127
128 | "no_appl"
129 [ c = const -> mk loc (Cst c)
130 | "("; l = LIST1 expr SEP ","; ")" -> tuple loc l
131 | "["; l = LIST0 seq_elem; e = OPT [ ";"; e = expr -> e ]; "]" ->
132 let e = match e with Some e -> e | None -> cst_nil in
133 List.fold_right
134 (fun x q ->
135 match x with
136 | `Elems l -> tuple_queue l q
137 | `Explode x -> mk x.loc (Op ("@",[x;q]))
138 ) l e
139 | t = [ a = TAG ->
140 mk loc (Cst (Types.Atom (Types.AtomPool.mk a)))
141 | "<"; e = expr LEVEL "no_appl" -> e ];
142 a = expr_attrib_spec; ">"; c = expr ->
143 mk loc (Xml (t, mk loc (Pair (a,c))))
144 | "{"; r = [ expr_record_spec | -> mk loc (RecordLitt []) ]; "}" -> r
145 | s = STRING2 ->
146 tuple loc (char_list loc s @ [cst_nil])
147 | a = LIDENT -> mk loc (Var a)
148 ]
149
150 ];
151
152 seq_elem: [
153 [ x = STRING1 -> `Elems (char_list loc x)
154 | e = expr LEVEL "no_appl" -> `Elems [e]
155 | "!"; e = expr LEVEL "no_appl" -> `Explode e
156 ]
157 ];
158
159 let_binding: [
160 [ "let"; p = pat; "="; e = expr -> (p,e)
161 | "let"; p = pat; ":"; t = pat; "="; e = expr -> (p, mk noloc (Forget (e,t)))
162 | "let"; "fun"; (f,a,b) = fun_decl ->
163 let p = match f with
164 | Some x -> mk loc (Capture x)
165 | _ -> failwith "Function name mandatory in let fun declarations"
166 in
167 let abst = { fun_name = f; fun_iface = a; fun_body = b } in
168 let e = mk loc (Abstraction abst) in
169 (p,e);
170 ]
171 ];
172
173 fun_decl: [
174 (* need an hack to do this, because both productions would
175 match [ OPT LIDENT; "("; pat ] .... *)
176 [ f = OPT LIDENT; "("; p1 = pat LEVEL "no_arrow";
177 res = [ "->"; p2 = pat;
178 a = [ ";"; a = LIST0 arrow SEP ";" -> a | -> [] ];
179 ")"; b = branches -> `Classic (p2,a,b)
180 | ":"; targ1 = pat;
181 args = LIST0 [ ","; arg = pat; ":"; targ = pat -> (arg,targ) ];
182 ")"; ":"; tres = pat ;
183 "="; body = expr ->
184 `Compact (targ1,args,tres,body)
185 ] ->
186 match res with
187 | `Classic (p2,a,b) -> f,(p1,p2)::a,b
188 | `Compact (targ1,args,tres,body) ->
189 let args = (p1,targ1) :: args in
190 let targ = multi_prod noloc (List.map snd args) in
191 let arg = multi_prod noloc (List.map fst args) in
192 let b = [arg, body] in
193 let a = [targ,tres] in
194 (f,a,b)
195 ]
196 ];
197
198 arrow: [
199 [ t1 = pat LEVEL "no_arrow"; "->"; t2 = pat -> (t1,t2)]
200 ];
201
202 branches: [
203 [ OPT "|"; l = LIST1 branch SEP "|" -> l ]
204 ];
205
206 branch: [
207 [ p = pat LEVEL "no_arrow"; "->"; e = expr -> (p,e) ]
208 ];
209
210
211 regexp: [
212 [ x = regexp; "|"; y = regexp -> Alt (x,y) ]
213 | [ x = regexp; y = regexp -> Seq (x,y) ]
214 | [ a = LIDENT; "::"; x = regexp -> SeqCapture (a,x) ]
215 | [ x = regexp; "*" -> Star x
216 | x = regexp; "*?" -> WeakStar x
217 | x = regexp; "+" -> Seq (x, Star x)
218 | x = regexp; "+?" -> Seq (x, WeakStar x)
219 | x = regexp; "?" -> Alt (x, Epsilon)
220 | x = regexp; "??" -> Alt (Epsilon, x) ]
221 | [ "("; x = regexp; ")" -> x
222 | "("; a = LIDENT; ":="; c = const; ")" -> Elem (mk loc (Constant (a,c)))
223 | UIDENT "PCDATA" -> string_regexp
224 | i = STRING1; "--"; j = STRING1 ->
225 let i = Chars.Unichar.from_char (parse_char loc i)
226 and j = Chars.Unichar.from_char (parse_char loc j) in
227 Elem (mk loc (Internal (Types.char (Chars.char_class i j))))
228 | s = STRING1 ->
229 let s = seq_of_string loc s in
230 List.fold_right
231 (fun (loc,c) accu ->
232 let c = Chars.Unichar.from_char c in
233 let c = Chars.atom c in
234 Seq (Elem (mk loc (Internal (Types.char c))), accu))
235 s
236 Epsilon
237 | e = pat LEVEL "simple" -> Elem e
238 ]
239 ];
240
241 pat: [
242 [ x = pat; "where";
243 b = LIST1 [ a = UIDENT; "="; y = pat -> (a,y)] SEP "and"
244 -> mk loc (Recurs (x,b)) ]
245 | RIGHTA [ x = pat; "->"; y = pat -> mk loc (Arrow (x,y)) ]
246 | "no_arrow" [ x = pat; "|"; y = pat -> mk loc (Or (x,y)) ]
247 | "simple" [ x = pat; "&"; y = pat -> mk loc (And (x,y))
248 | x = pat; "\\"; y = pat -> mk loc (Diff (x,y)) ]
249 |
250 [ "{"; r = record_spec; "}" -> r
251 | LIDENT "_" -> mk loc (Internal Types.any)
252 | a = LIDENT -> mk loc (Capture a)
253 | "("; a = LIDENT; ":="; c = const; ")" -> mk loc (Constant (a,c))
254 | a = UIDENT -> mk loc (PatVar a)
255 | i = INT ; "--"; j = INT ->
256 let i = Big_int.big_int_of_string i
257 and j = Big_int.big_int_of_string j in
258 mk loc (Internal (Types.interval (Intervals.bounded i j)))
259 | i = INT ->
260 let i = Big_int.big_int_of_string i in
261 mk loc (Internal (Types.interval (Intervals.atom i)))
262 | "*"; "--"; j = INT ->
263 let j = Big_int.big_int_of_string j in
264 mk loc (Internal (Types.interval (Intervals.left j)))
265 | i = INT; "--"; "*" ->
266 let i = Big_int.big_int_of_string i in
267 mk loc (Internal (Types.interval (Intervals.right i)))
268 | i = char ->
269 mk loc (Internal (Types.char (Chars.char_class i i)))
270 | i = char ; "--"; j = char ->
271 mk loc (Internal (Types.char (Chars.char_class i j)))
272 | c = const -> mk loc (Internal (Types.constant c))
273 | "("; l = LIST1 pat SEP ","; ")" -> multi_prod loc l
274 | "["; r = [ r = regexp -> r | -> Epsilon ];
275 q = [ ";"; q = pat -> q
276 | -> mk noloc (Internal (Sequence.nil_type)) ];
277 "]" -> mk loc (Regexp (r,q))
278 | t = [
279 [ "<"; LIDENT "_" -> mk loc (Internal (Types.atom (Atoms.any)))
280 | a = TAG ->
281 mk loc
282 (Internal (Types.atom (Atoms.atom (Types.AtomPool.mk a)))) ]
283 | [ "<"; t = pat -> t ]
284 ];
285 a = attrib_spec; ">"; c = pat ->
286 mk loc (XmlT (t, multi_prod loc [a;c]))
287 | s = STRING2 ->
288 let s = seq_of_string loc s in
289 let s = List.map
290 (fun (loc,c) ->
291 mk loc (Internal
292 (Types.char
293 (Chars.atom
294 (Chars.Unichar.from_char c))))) s in
295 let s = s @ [mk loc (Internal (Sequence.nil_type))] in
296 multi_prod loc s
297 ]
298
299 ];
300
301 record_spec:
302 [ [ r = LIST0 [ l = [LIDENT | UIDENT]; "=";
303 o = [ "?" -> true | -> false];
304 x = pat ->
305 mk loc (Record (Types.LabelPool.mk l,o,x))
306 ] SEP ";" ->
307 match r with
308 | [] -> mk loc (Internal Types.Record.any)
309 | h::t -> List.fold_left (fun t1 t2 -> mk loc (And (t1,t2))) h t
310 ] ];
311
312 char:
313 [
314 [ c = STRING1 -> Chars.Unichar.from_char (parse_char loc c)
315 | "!"; i = INT -> Chars.Unichar.from_int (int_of_string i) ]
316 ];
317
318
319 const:
320 [
321 [ i = INT -> Types.Integer (Big_int.big_int_of_string i)
322 | "`"; a = [LIDENT | UIDENT] -> Types.Atom (Types.AtomPool.mk a)
323 | c = char -> Types.Char c ]
324 ];
325
326
327 attrib_spec:
328 [ [ r = record_spec -> r | "("; t = pat; ")" -> t ] ];
329
330 expr_record_spec:
331 [ [ r = LIST1
332 [ l = [LIDENT | UIDENT]; "="; x = expr ->
333 (Types.LabelPool.mk l,x) ]
334 SEP ";" ->
335 mk loc (RecordLitt r)
336 ] ];
337
338 expr_attrib_spec:
339 [ [ r = expr_record_spec -> r ]
340 | [ e = expr LEVEL "no_appl" -> e
341 | -> mk loc (RecordLitt [])
342 ]
343 ];
344 END
345
346 let pat' = Grammar.Entry.create gram "type/pattern expression"
347 EXTEND GLOBAL: pat pat';
348 pat': [ [ p = pat; EOI -> p ] ];
349 END
350
351 let pat = Grammar.Entry.parse pat
352 and expr = Grammar.Entry.parse expr
353 and prog = Grammar.Entry.parse prog
354
355 module From_string = struct
356 let pat s = Grammar.Entry.parse pat' (Stream.of_string s)
357 let expr s = expr (Stream.of_string s)
358 end
359

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.5