Injecting External State into Parser Logic

Standard parser definitions typically operate solely on the input string. However, when generating an AST, you often need external context or configuration flags to influence how nodes are built.

Consider a scenario where you want to apply a multiplier to every numeric literal encountered during parsing. You can declare a state parameter directly in the grammar definition:

grammar(multiplier: i32);

This multiplier variable becomes available within your grammar rules. For instance, the Num rule can utilize this value to transform the token immediately:

Num: i32 = {
    r"[0-9]+" => i32::from_str(<>).unwrap() * multiplier,
};

When invoking the parser, you provide the state value as the first argument before the input string:

#[test]
fn test_scaled_calculation() {
    let factor = 2;
    let result = calculator8::ExprParser::new()
        .parse(factor, "11 * 22 + 33")
        .unwrap();
    
    // Expected: 11*2=22, 22*2=44, 33*2=66
    assert_eq!(&format!("{:?}", result), "((22 * 44) + 66)");
}

For complex use cases involving custom tree structures, passing state allows the parser to construct specific AST nodes dynamically based on the provided context.

Constraint: The state parameter must implement the Copy trait. If you need to pass a type that does not implement Copy, pass a reference to the data instead of the value itself.

Tags: rust parsing Pest AST State Management

Posted on Sun, 05 Jul 2026 16:58:05 +0000 by zkent