mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 06:48:48 +00:00
Ostap expr combinator (no associativity, no attributes yet)
This commit is contained in:
parent
33ec55e76e
commit
d93995c444
3 changed files with 95 additions and 0 deletions
73
stdlib/Expr.expr
Normal file
73
stdlib/Expr.expr
Normal 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
|
||||||
|
|
||||||
|
*)
|
||||||
6
stdlib/regression/orig/test11.log
Normal file
6
stdlib/regression/orig/test11.log
Normal 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")))
|
||||||
16
stdlib/regression/test11.expr
Normal file
16
stdlib/regression/test11.expr
Normal 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)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue