R!用 Rust 搓了一个表达式引擎

1 天前
 ukuq

https://docs.rs/value-expr/0.1.1/value_expr/

https://github.com/ukuq/value-expr

基于特定场景简化了,语法定义上很简单,条件、变量、循环都有了,还能结合 FuncLike 实现一些更复杂的场景

Value:
    i32
    | Unary
    | Binary
    | Assign
    | Paren
    | FuncLike
    | Ident
Unary:
    - Value
    | ! Value
Binary:
    Value + Value
    | Value - Value
    | Value * Value
    | Value / Value
    | Value % Value
    | Value ^ Value
    | Value & Value
    | Value | Value
    | Value << Value
    | Value >> Value
    | Value == Value
    | Value != Value
    | Value > Value
    | Value < Value
    | Value >= Value
    | Value <= Value
    | Value && Value
    | Value || Value
Assign:
    Ident = Value
    | Ident += Value
    | Ident -= Value
    | Ident *= Value
    | Ident /= Value
    | Ident %= Value
    | Ident ^= Value
    | Ident &= Value
    | Ident |= Value
    | Ident <<= Value
    | Ident >>= Value
Paren:
    ( Values )
FuncLike:
    Ident ( Values )
Values:
    <nothing>
    | ValuesNext
ValuesNext:
    Value
    | Value , ValuesNext
Ident:
    <the rust lang ident>

样例也很简单

fn demo() {
    let mut ctx = DemoContext::default();
    //条件
    ctx.exec(
        "(
            _assert(_if(1,2,3)==2),
            _assert(_if(-1,2,3)==3),
            )",
    );
    //函数
    ctx.exec(
        "(
            _fn(add,a+b,a,b),
            _assert(add(1)==1),
            _assert(add(1,2)==3),
            _assert(_call(add,1,2)==3)
            )",
    );
    //循环
    ctx.exec(
        "_log(_while,
            i=10,
            _while(i<100000,
                _if(i%10000==0,_log(i_is,i)),
                i+=1,
                i
            )
            )",
    );
    //递归
    ctx.exec(
        "(
            _fn(fib1,_if(n<2,a2,fib1(n-1,a2,a1+a2)),n,a1,a2),
            _fn(fib,fib1(n,1,1),n),
            _log(fib,fib(0),fib(1),fib(2),fib(3),fib(10),fib(19)),
            _assert(6765==fib(19))
            )",
    );
    //作用域
    ctx.exec(
        "(
            _scope(a=100,_assert(a==100)),
            _scope(a=100,_scope(_assert(a==100))),
            _scope(a=100,a=200,_assert(a==200)),
            _scope(a=100,_scope(a=200),_assert(a==100)),
            _fn(f1,_assert(a==0)),
            _scope(a=100,_fn(f1,_assert(a==100))),
            _scope(a=100,_fn(f1,(a=200,_assert(a==200))),_assert(a==100))
            )",
    );
}
671 次点击
所在节点    分享创造
1 条回复
3085570450tt
1 天前
已 star! 感觉可以做为学习的小项目

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1118696

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX