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

Contents of /parser/parser.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 151 - (show annotations)
Tue Jul 10 17:10:43 2007 UTC (5 years, 10 months ago) by abate
File size: 11543 byte(s)
[r2002-11-25 13:54:34 by cvscast] Empty log message

Original author: cvscast
Date: 2002-11-25 13:54:35+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 | LIDENT "compile2"; t = pat; p = LIST1 pat -> `Compile2 (t,p)
79 ]
80 ];
81
82 expr: [
83 "top" RIGHTA
84 [ "match"; e = SELF; "with"; b = branches -> mk loc (Match (e,b))
85 | "try"; e = SELF; "with"; b = branches ->
86 let default =
87 (mk noloc (Capture "x"),
88 mk noloc (Op ("raise",[mk noloc (Var "x")]))) in
89 mk loc (Try (e,b@[default]))
90 | "map"; e = SELF; "with"; b = branches -> mk loc (Map (e,b))
91 | "transform"; e = SELF; "with"; b = branches ->
92 let default = mk noloc (Capture "x"), cst_nil in
93 mk loc (Op ("flatten", [mk loc (Map (e,b@[default]))]))
94 | "fun"; (f,a,b) = fun_decl ->
95 mk loc (Abstraction { fun_name = f; fun_iface = a; fun_body = b })
96 | (p,e1) = let_binding; "in"; e2 = expr LEVEL "top"->
97 mk loc (Match (e1,[p,e2]))
98 | e = expr; ":"; p = pat ->
99 mk loc (Forget (e,p))
100 ]
101
102
103 |
104 [ e1 = expr; op = ["+" | "-" | "@"]; e2 = expr -> mk loc (Op (op,[e1;e2]))
105 ]
106 |
107 [ e1 = expr; op = ["*"]; e2 = expr -> mk loc (Op (op,[e1;e2]))
108 | e = expr; op = "/"; p = pat ->
109
110 let tag = mk loc (Internal (Types.atom (Atoms.any))) in
111 let att = mk loc (Internal Types.Record.any) in
112 let any = mk loc (Internal (Types.any)) in
113 let re = Star(Alt(SeqCapture("x",Elem p), Elem any)) in
114 let ct = mk loc (Regexp (re,any)) in
115 let p = mk loc (XmlT (tag, multi_prod loc [att;ct])) in
116 let b = (p, mk loc (Var "x")) in
117 mk loc (Op ("flatten", [mk loc (Map (e,[b]))]))
118 ]
119 |
120 [ e = expr; "."; l = [LIDENT | UIDENT] ->
121 mk loc (Dot (e,Types.LabelPool.mk l))
122 ]
123
124 |
125 [ op = [ LIDENT "flatten"
126 | LIDENT "load_xml"
127 | LIDENT "print_xml"
128 | LIDENT "print"
129 | LIDENT "raise"
130 | LIDENT "int_of"
131 | LIDENT "string_of"
132 ];
133 e = expr -> mk loc (Op (op,[e]))
134 | op = [ LIDENT "dump_to_file" ];
135 e1 = expr LEVEL "no_appl"; e2 = expr -> mk loc (Op (op, [e1;e2]))
136 | e1 = SELF; LIDENT "div"; e2 = expr -> mk loc (Op ("/", [e1;e2]))
137 | e1 = SELF; e2 = expr -> mk loc (Apply (e1,e2))
138 ]
139
140 | "no_appl"
141 [ c = const -> mk loc (Cst c)
142 | "("; l = LIST1 expr SEP ","; ")" -> tuple loc l
143 | "["; l = LIST0 seq_elem; e = OPT [ ";"; e = expr -> e ]; "]" ->
144 let e = match e with Some e -> e | None -> cst_nil in
145 List.fold_right
146 (fun x q ->
147 match x with
148 | `Elems l -> tuple_queue l q
149 | `Explode x -> mk x.loc (Op ("@",[x;q]))
150 ) l e
151 | t = [ a = TAG ->
152 mk loc (Cst (Types.Atom (Types.AtomPool.mk a)))
153 | "<"; e = expr LEVEL "no_appl" -> e ];
154 a = expr_attrib_spec; ">"; c = expr ->
155 mk loc (Xml (t, mk loc (Pair (a,c))))
156 | "{"; r = [ expr_record_spec | -> mk loc (RecordLitt []) ]; "}" -> r
157 | s = STRING2 ->
158 tuple loc (char_list loc s @ [cst_nil])
159 | a = LIDENT -> mk loc (Var a)
160 ]
161
162 ];
163
164 seq_elem: [
165 [ x = STRING1 -> `Elems (char_list loc x)
166 | e = expr LEVEL "no_appl" -> `Elems [e]
167 | "!"; e = expr LEVEL "no_appl" -> `Explode e
168 ]
169 ];
170
171 let_binding: [
172 [ "let"; p = pat; "="; e = expr -> (p,e)
173 | "let"; p = pat; ":"; t = pat; "="; e = expr -> (p, mk noloc (Forget (e,t)))
174 | "let"; "fun"; (f,a,b) = fun_decl ->
175 let p = match f with
176 | Some x -> mk loc (Capture x)
177 | _ -> failwith "Function name mandatory in let fun declarations"
178 in
179 let abst = { fun_name = f; fun_iface = a; fun_body = b } in
180 let e = mk loc (Abstraction abst) in
181 (p,e);
182 ]
183 ];
184
185 fun_decl: [
186 (* need an hack to do this, because both productions would
187 match [ OPT LIDENT; "("; pat ] .... *)
188 [ f = OPT LIDENT; "("; p1 = pat LEVEL "no_arrow";
189 res = [ "->"; p2 = pat;
190 a = [ ";"; a = LIST0 arrow SEP ";" -> a | -> [] ];
191 ")"; b = branches -> `Classic (p2,a,b)
192 | ":"; targ1 = pat;
193 args = LIST0 [ ","; arg = pat; ":"; targ = pat -> (arg,targ) ];
194 ")"; ":"; tres = pat ;
195 "="; body = expr ->
196 `Compact (targ1,args,tres,body)
197 ] ->
198 match res with
199 | `Classic (p2,a,b) -> f,(p1,p2)::a,b
200 | `Compact (targ1,args,tres,body) ->
201 let args = (p1,targ1) :: args in
202 let targ = multi_prod noloc (List.map snd args) in
203 let arg = multi_prod noloc (List.map fst args) in
204 let b = [arg, body] in
205 let a = [targ,tres] in
206 (f,a,b)
207 ]
208 ];
209
210 arrow: [
211 [ t1 = pat LEVEL "no_arrow"; "->"; t2 = pat -> (t1,t2)]
212 ];
213
214 branches: [
215 [ OPT "|"; l = LIST1 branch SEP "|" -> l ]
216 ];
217
218 branch: [
219 [ p = pat LEVEL "no_arrow"; "->"; e = expr -> (p,e) ]
220 ];
221
222
223 regexp: [
224 [ x = regexp; "|"; y = regexp -> Alt (x,y) ]
225 | [ x = regexp; y = regexp -> Seq (x,y) ]
226 | [ a = LIDENT; "::"; x = regexp -> SeqCapture (a,x) ]
227 | [ x = regexp; "*" -> Star x
228 | x = regexp; "*?" -> WeakStar x
229 | x = regexp; "+" -> Seq (x, Star x)
230 | x = regexp; "+?" -> Seq (x, WeakStar x)
231 | x = regexp; "?" -> Alt (x, Epsilon)
232 | x = regexp; "??" -> Alt (Epsilon, x) ]
233 | [ "("; x = regexp; ")" -> x
234 | "("; a = LIDENT; ":="; c = const; ")" -> Elem (mk loc (Constant (a,c)))
235 | UIDENT "PCDATA" -> string_regexp
236 | i = STRING1; "--"; j = STRING1 ->
237 let i = Chars.Unichar.from_char (parse_char loc i)
238 and j = Chars.Unichar.from_char (parse_char loc j) in
239 Elem (mk loc (Internal (Types.char (Chars.char_class i j))))
240 | s = STRING1 ->
241 let s = seq_of_string loc s in
242 List.fold_right
243 (fun (loc,c) accu ->
244 let c = Chars.Unichar.from_char c in
245 let c = Chars.atom c in
246 Seq (Elem (mk loc (Internal (Types.char c))), accu))
247 s
248 Epsilon
249 | e = pat LEVEL "simple" -> Elem e
250 ]
251 ];
252
253 pat: [
254 [ x = pat; "where";
255 b = LIST1 [ a = UIDENT; "="; y = pat -> (a,y)] SEP "and"
256 -> mk loc (Recurs (x,b)) ]
257 | RIGHTA [ x = pat; "->"; y = pat -> mk loc (Arrow (x,y)) ]
258 | "no_arrow" [ x = pat; "|"; y = pat -> mk loc (Or (x,y)) ]
259 | "simple" [ x = pat; "&"; y = pat -> mk loc (And (x,y))
260 | x = pat; "\\"; y = pat -> mk loc (Diff (x,y)) ]
261 |
262 [ "{"; r = record_spec; "}" -> r
263 | LIDENT "_" -> mk loc (Internal Types.any)
264 | a = LIDENT -> mk loc (Capture a)
265 | "("; a = LIDENT; ":="; c = const; ")" -> mk loc (Constant (a,c))
266 | a = UIDENT -> mk loc (PatVar a)
267 | i = INT ; "--"; j = INT ->
268 let i = Big_int.big_int_of_string i
269 and j = Big_int.big_int_of_string j in
270 mk loc (Internal (Types.interval (Intervals.bounded i j)))
271 | i = INT ->
272 let i = Big_int.big_int_of_string i in
273 mk loc (Internal (Types.interval (Intervals.atom i)))
274 | "*"; "--"; j = INT ->
275 let j = Big_int.big_int_of_string j in
276 mk loc (Internal (Types.interval (Intervals.left j)))
277 | i = INT; "--"; "*" ->
278 let i = Big_int.big_int_of_string i in
279 mk loc (Internal (Types.interval (Intervals.right i)))
280 | i = char ->
281 mk loc (Internal (Types.char (Chars.char_class i i)))
282 | i = char ; "--"; j = char ->
283 mk loc (Internal (Types.char (Chars.char_class i j)))
284 | c = const -> mk loc (Internal (Types.constant c))
285 | "("; l = LIST1 pat SEP ","; ")" -> multi_prod loc l
286 | "["; r = [ r = regexp -> r | -> Epsilon ];
287 q = [ ";"; q = pat -> q
288 | -> mk noloc (Internal (Sequence.nil_type)) ];
289 "]" -> mk loc (Regexp (r,q))
290 | t = [
291 [ "<"; LIDENT "_" -> mk loc (Internal (Types.atom (Atoms.any)))
292 | a = TAG ->
293 mk loc
294 (Internal (Types.atom (Atoms.atom (Types.AtomPool.mk a)))) ]
295 | [ "<"; t = pat -> t ]
296 ];
297 a = attrib_spec; ">"; c = pat ->
298 mk loc (XmlT (t, multi_prod loc [a;c]))
299 | s = STRING2 ->
300 let s = seq_of_string loc s in
301 let s = List.map
302 (fun (loc,c) ->
303 mk loc (Internal
304 (Types.char
305 (Chars.atom
306 (Chars.Unichar.from_char c))))) s in
307 let s = s @ [mk loc (Internal (Sequence.nil_type))] in
308 multi_prod loc s
309 ]
310
311 ];
312
313 record_spec:
314 [ [ r = LIST0 [ l = [LIDENT | UIDENT]; "=";
315 o = [ "?" -> true | -> false];
316 x = pat ->
317 mk loc (Record (Types.LabelPool.mk l,o,x))
318 ] SEP ";" ->
319 match r with
320 | [] -> mk loc (Internal Types.Record.any)
321 | h::t -> List.fold_left (fun t1 t2 -> mk loc (And (t1,t2))) h t
322 ] ];
323
324 char:
325 [
326 [ c = STRING1 -> Chars.Unichar.from_char (parse_char loc c)
327 | "!"; i = INT -> Chars.Unichar.from_int (int_of_string i) ]
328 ];
329
330
331 const:
332 [
333 [ i = INT -> Types.Integer (Big_int.big_int_of_string i)
334 | "`"; a = [LIDENT | UIDENT] -> Types.Atom (Types.AtomPool.mk a)
335 | c = char -> Types.Char c ]
336 ];
337
338
339 attrib_spec:
340 [ [ r = record_spec -> r | "("; t = pat; ")" -> t ] ];
341
342 expr_record_spec:
343 [ [ r = LIST1
344 [ l = [LIDENT | UIDENT]; "="; x = expr ->
345 (Types.LabelPool.mk l,x) ]
346 SEP ";" ->
347 mk loc (RecordLitt r)
348 ] ];
349
350 expr_attrib_spec:
351 [ [ r = expr_record_spec -> r ]
352 | [ e = expr LEVEL "no_appl" -> e
353 | -> mk loc (RecordLitt [])
354 ]
355 ];
356 END
357
358 let pat' = Grammar.Entry.create gram "type/pattern expression"
359 EXTEND GLOBAL: pat pat';
360 pat': [ [ p = pat; EOI -> p ] ];
361 END
362
363 let pat = Grammar.Entry.parse pat
364 and expr = Grammar.Entry.parse expr
365 and prog = Grammar.Entry.parse prog
366
367 module From_string = struct
368 let pat s = Grammar.Entry.parse pat' (Stream.of_string s)
369 let expr s = expr (Stream.of_string s)
370 end
371

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