OCaml parser combinator that compiles to direct recursive descent
5

Configure Feed

Select the types of activity you want to include in your feed.

ppx_combin / src / optimise.ml
4.1 kB 115 lines
1open Ir 2 3let rec optimise expr = 4 match expr with 5 | Map { f; p; loc } -> 6 let p' = optimise p in 7 (match p' with 8 | Pure { value; _ } -> 9 Pure { loc; value = [%expr [%e f] [%e value]] } 10 | Map { f = f2; p = p2; _ } -> 11 Map { loc; f = [%expr fun x -> [%e f] ([%e f2] x)]; p = p2 } 12 | _ -> Map { loc; f; p = p' }) 13 14 | SeqRight { p; q; loc } -> 15 let p' = optimise p in 16 let q' = optimise q in 17 let p' = match p' with 18 | Many { p = inner; loc = l } -> SkipMany { loc = l; p = inner } 19 | Some_ { p = inner; loc = l } -> SkipSome { loc = l; p = inner } 20 | _ -> p' 21 in 22 (match p' with 23 | Pure _ -> q' 24 | _ -> SeqRight { loc; p = p'; q = q' }) 25 26 | SeqLeft { p; q; loc } -> 27 let p' = optimise p in 28 let q' = optimise q in 29 let q' = match q' with 30 | Many { p = inner; loc = l } -> SkipMany { loc = l; p = inner } 31 | Some_ { p = inner; loc = l } -> SkipSome { loc = l; p = inner } 32 | _ -> q' 33 in 34 (match q' with 35 | Pure _ -> p' 36 | _ -> SeqLeft { loc; p = p'; q = q' }) 37 38 | Apply { pf; px; loc } -> 39 let pf' = optimise pf in 40 let px' = optimise px in 41 (match pf', px' with 42 | Pure { value = f; _ }, Pure { value = x; _ } -> 43 Pure { loc; value = [%expr [%e f] [%e x]] } 44 | Pure { value = f; _ }, _ -> 45 Map { loc; f; p = px' } 46 | _, Pure { value = x; _ } -> 47 Map { loc; f = [%expr fun f -> f [%e x]]; p = pf' } 48 | _ -> Apply { loc; pf = pf'; px = px' }) 49 50 | Alt { p; q; loc } -> 51 let p' = optimise p in 52 let q' = optimise q in 53 (match p' with 54 | Fail _ -> q' 55 | _ -> Alt { loc; p = p'; q = q' }) 56 57 | Bind { p; f; loc } -> 58 let p' = optimise p in 59 (match p' with 60 | Pure { value; _ } -> 61 Bind { loc; p = Pure { loc; value = [%expr ()] }; f = [%expr fun () -> [%e f] [%e value]] } 62 | _ -> Bind { loc; p = p'; f }) 63 64 | Attempt { p; loc } -> 65 Attempt { loc; p = optimise p } 66 | Lookahead { p; loc } -> 67 Lookahead { loc; p = optimise p } 68 | NotFollowedBy { p; loc } -> 69 NotFollowedBy { loc; p = optimise p } 70 | Many { p; loc } -> 71 Many { loc; p = optimise p } 72 | Some_ { p; loc } -> 73 Some_ { loc; p = optimise p } 74 | SkipMany { p; loc } -> 75 SkipMany { loc; p = optimise p } 76 | SkipSome { p; loc } -> 77 SkipSome { loc; p = optimise p } 78 | TakeWhile _ -> expr 79 | Optional { p; loc } -> 80 Optional { loc; p = optimise p } 81 | Option { default; p; loc } -> 82 Option { loc; default; p = optimise p } 83 | SepBy { p; sep; loc } -> 84 SepBy { loc; p = optimise p; sep = optimise sep } 85 | SepBy1 { p; sep; loc } -> 86 SepBy1 { loc; p = optimise p; sep = optimise sep } 87 | EndBy { p; sep; loc } -> 88 EndBy { loc; p = optimise p; sep = optimise sep } 89 | EndBy1 { p; sep; loc } -> 90 EndBy1 { loc; p = optimise p; sep = optimise sep } 91 | ManyTill { p; end_; loc } -> 92 ManyTill { loc; p = optimise p; end_ = optimise end_ } 93 | Count { n; p; loc } -> 94 Count { loc; n; p = optimise p } 95 | Between { open_; close; p; loc } -> 96 Between { loc; open_ = optimise open_; close = optimise close; p = optimise p } 97 | ChainL { p; op; loc } -> 98 ChainL { loc; p = optimise p; op = optimise op } 99 | ChainL1 { p; op; loc } -> 100 ChainL1 { loc; p = optimise p; op = optimise op } 101 | ChainR { p; op; loc } -> 102 ChainR { loc; p = optimise p; op = optimise op } 103 | ChainR1 { p; op; loc } -> 104 ChainR1 { loc; p = optimise p; op = optimise op } 105 | Choice { ps; label; loc } -> 106 let ps' = List.map optimise ps in 107 let ps'' = List.filter (function Fail _ -> false | _ -> true) ps' in 108 Choice { loc; ps = (if ps'' = [] then ps' else ps''); label } 109 | Label { p; label; loc } -> 110 Label { loc; p = optimise p; label } 111 | Memo { name; p; loc } -> 112 Memo { loc; name; p = optimise p } 113 114 | Pure _ | Fail _ | Satisfy _ | Any _ | Eof _ | Token _ | Tokens _ 115 | OneOf _ | NoneOf _ | Cut _ | Fix _ | Var _ -> expr