Ostap expr combinator (no associativity, no attributes yet)

This commit is contained in:
Dmitry Boulytchev 2020-01-27 00:36:07 +03:00
parent 33ec55e76e
commit d93995c444
3 changed files with 95 additions and 0 deletions

73
stdlib/Expr.expr Normal file
View file

@ -0,0 +1,73 @@
import Ostap;
import List;
import Fun;
--- ops -> fun (x, y) {x `op` y}
fun altl (ps) {
case ps of
p : ps -> foldl (infix |, p, ps)
esac
}
public fun expr (ops, opnd) {
fun inner (ops) {
case ops of
{} -> opnd
| level : tl ->
local lops = altl (level),
next = inner (tl);
fun this (k) {
next |> fun (l) {lops |> fun (op) {this @ fun (r) {op (l, r)}}}
| next
$ k
}
this
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
*)

View file

@ -0,0 +1,6 @@
Succ ("a")
Succ (Add ("a", "a"))
Succ (Sub ("a", "a"))
Succ (Add ("a", Sub ("a", "a")))
Succ (Add ("a", Mul ("a", "a")))
Succ (Sub (Mul ("a", "a"), Div ("a", "a")))

View file

@ -0,0 +1,16 @@
import Ostap;
import Expr;
local a = token ("a"),
add = token ("+") @ lift (fun (l, r) {Add (l, r)}),
sub = token ("-") @ lift (fun (l, r) {Sub (l, r)}),
mul = token ("*") @ lift (fun (l, r) {Mul (l, r)}),
div = token ("/") @ lift (fun (l, r) {Div (l, r)}),
exp = expr ({{add, sub}, {mul, div}}, a);
printf ("%s\n", parseString (exp |> bypass (eof), "a").string);
printf ("%s\n", parseString (exp |> bypass (eof), "a+a").string);
printf ("%s\n", parseString (exp |> bypass (eof), "a-a").string);
printf ("%s\n", parseString (exp |> bypass (eof), "a+a-a").string);
printf ("%s\n", parseString (exp |> bypass (eof), "a+a*a").string);
printf ("%s\n", parseString (exp |> bypass (eof), "a*a-a/a").string)