Skip to main content

fold_fn

Function fold_fn 

pub fn fold_fn<T, L, R>(on_leaf: L, on_rule: R) -> FnFold<L, R>
where L: FnMut(&str, FoldLeaf<'_>) -> T, R: FnMut(&str, Vec<T>) -> T,
Expand description

Build a Fold from two closures — two matches with one shape: on_leaf(token_type_name, leaf) -> T and on_rule(rule_name, children) -> T. (A placeholder hole reaches on_leaf with the name "".)

use hyperlark::{fold_fn, Lark, LarkOptions};

let parser = Lark::from_lark_source(
    r#"
    ?start: sum
    ?sum: atom | sum "+" atom -> add
    ?atom: NUMBER             -> number
    %import common.NUMBER
    %import common.WS_INLINE
    %ignore WS_INLINE
    "#,
    LarkOptions::default(),
).unwrap();

let mut calc = fold_fn(
    |name, leaf| match name {
        "NUMBER" => leaf.text().parse().unwrap(),
        _ => 0.0, // a `[...]` placeholder hole (name "")
    },
    |name, kids: Vec<f64>| match name {
        "add" => kids[0] + kids[1],
        _ => kids[0], // number
    },
);
let result = parser.parse("1 + 2 + 39").unwrap();
assert_eq!(result.fold(&mut calc), 42.0);