V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
ukuq
V2EX  ›  分享创造

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

  •  
  •   ukuq · 22 小时 7 分钟前 · 541 次点击

    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))
                )",
        );
    }
    
    1 条回复    2025-03-16 00:51:05 +08:00
    3085570450tt
        1
    3085570450tt  
       17 小时 55 分钟前
    已 star! 感觉可以做为学习的小项目
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2551 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 10:46 · PVG 18:46 · LAX 03:46 · JFK 06:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.