diff --git a/src/Language.ml b/src/Language.ml index ab9f54873..eb9c7d777 100644 --- a/src/Language.ml +++ b/src/Language.ml @@ -448,10 +448,43 @@ module Expr = | Skip -> Skip | e -> Ignore (balance_value e) + (* ======= *) + + let left f c x y = f (c x) y + let right f c x y = c (f x y) + + let expr f ops opnd = + let ops = + Array.map + (fun (assoc, list) -> + let g = match assoc with `Lefta | `Nona -> left | `Righta -> right in + assoc = `Nona, altl (List.map (fun (oper, sema) -> ostap (!(oper) {g sema})) list) + ) + ops + in + let n = Array.length ops in + let op i = snd ops.(i) in + let nona i = fst ops.(i) in + let id x = x in + let ostap ( + inner[l][c]: f[ostap ( + {n = l } => x:opnd {c x} + | {n > l && not (nona l)} => x:inner[l+1][id] b:(-o:op[l] inner[l][o c x])? { + match b with None -> c x | Some x -> x + } + | {n > l && nona l} => x:inner[l+1][id] b:(op[l] inner[l+1][id])? { + c (match b with None -> x | Some (o, y) -> o id x y) + })] + ) + in + ostap (inner[0][id]) + + (* ======= *) + ostap ( parse[infix]: h:basic[infix] t:(-";" parse[infix])? {match t with None -> h | Some t -> Seq (h, t)}; basic[infix]: - !(Ostap.Util.expr + !(expr (fun x -> x) (Array.map (fun (a, l) -> a, List.map (fun (s, f) -> ostap (- $(s)), f) l) infix) (primary infix));