2020-01-27 00:36:07 +03:00
|
|
|
import Ostap;
|
|
|
|
|
import List;
|
|
|
|
|
import Fun;
|
|
|
|
|
|
2020-01-30 23:36:15 +03:00
|
|
|
public fun left (f) {
|
|
|
|
|
fun (c, x) {
|
|
|
|
|
fun (y) {
|
|
|
|
|
f (c (x), y)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun right (f) {
|
|
|
|
|
fun (c, x) {
|
|
|
|
|
fun (y) {
|
|
|
|
|
c (f (x, y))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-27 00:36:07 +03:00
|
|
|
--- ops -> fun (x, y) {x `op` y}
|
2020-01-30 23:36:15 +03:00
|
|
|
fun altl (level) {
|
|
|
|
|
case level of
|
|
|
|
|
[assoc, ps] ->
|
2020-01-31 01:30:03 +03:00
|
|
|
local assfun = case assoc of Left -> left | Right -> right | Nona -> left esac;
|
2020-01-30 23:36:15 +03:00
|
|
|
case map (fun (p) {
|
|
|
|
|
case p of
|
2020-01-31 01:30:03 +03:00
|
|
|
[op, sema] -> op @ lift(assfun (sema))
|
2020-01-30 23:36:15 +03:00
|
|
|
esac
|
|
|
|
|
}, ps) of
|
|
|
|
|
p : ps -> foldl (infix |, p, ps)
|
|
|
|
|
esac
|
2020-01-27 00:36:07 +03:00
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun expr (ops, opnd) {
|
|
|
|
|
fun inner (ops) {
|
|
|
|
|
case ops of
|
2020-01-30 23:36:15 +03:00
|
|
|
{} -> fun (c) {opnd @ c}
|
2020-01-27 00:36:07 +03:00
|
|
|
| level : tl ->
|
|
|
|
|
local lops = altl (level),
|
|
|
|
|
next = inner (tl);
|
|
|
|
|
|
2020-01-31 01:30:03 +03:00
|
|
|
case level.fst of
|
|
|
|
|
Nona ->
|
|
|
|
|
fun this (c) {
|
|
|
|
|
next (id) |> fun (l) {lops |> fun (op) {next (id) @ fun (r) {c (op)(id, l)(r)}}}
|
|
|
|
|
| next (id) @ c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this
|
|
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
fun this (c) {
|
|
|
|
|
next (id) |> fun (l) {lops |> fun (op) {this (op (c, l))}}
|
|
|
|
|
| next (id) @ c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this
|
|
|
|
|
esac
|
2020-01-27 00:36:07 +03:00
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inner (ops)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(*
|
|
|
|
|
Just some memo from OCaml's Ostap. Will be removed when done.
|
|
|
|
|
|
|
|
|
|
let left f c x a y = f (c x) a y
|
|
|
|
|
let right f c x a y = c (f x a y)
|
|
|
|
|
|
|
|
|
|
fun expr (ops, opnd, atr) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ops = [is_nona, (atrs, alt_parser at the level),
|
|
|
|
|
...
|
|
|
|
|
]
|
|
|
|
|
let expr f ops opnd atr =
|
|
|
|
|
let ops =
|
|
|
|
|
Array.map
|
|
|
|
|
(fun (assoc, (atrs, list)) ->
|
|
|
|
|
let g = match assoc with `Lefta | `Nona -> left | `Righta -> right in
|
|
|
|
|
assoc = `Nona, (atrs, altl (List.map (fun (oper, sema) -> ostap (!(oper) {g sema})) list))
|
|
|
|
|
)
|
|
|
|
|
ops
|
|
|
|
|
in
|
|
|
|
|
let atrr i atr = snd (fst (snd ops.(i)) atr) in
|
|
|
|
|
let atrl i atr = fst (fst (snd ops.(i)) atr) in
|
|
|
|
|
let n = Array.length ops in
|
|
|
|
|
let op i = snd (snd ops.(i)) in
|
|
|
|
|
let nona i = fst ops.(i) in
|
|
|
|
|
let id x = x in
|
|
|
|
|
let ostap (
|
|
|
|
|
inner[l][c][atr]: f[ostap (
|
|
|
|
|
{n = l } => x:opnd[atr] {c x}
|
|
|
|
|
| {n > l && not (nona l)} => (-x:inner[l+1][id][atrl l atr] -o:op[l] y:inner[l][o c x atr][atrr l atr] |
|
|
|
|
|
x:inner[l+1][id][atr] {c x})
|
|
|
|
|
| {n > l && nona l} => (x:inner[l+1][id][atrl l atr] o:op[l] y:inner[l+1][id][atrr l atr] {c (o id x atr y)} |
|
|
|
|
|
x:inner[l+1][id][atr] {c x})
|
|
|
|
|
)]
|
|
|
|
|
)
|
|
|
|
|
in
|
|
|
|
|
ostap (inner[0][id][atr])d
|
|
|
|
|
|
|
|
|
|
*)
|