kevinmehall/rust-peg

feat: mut variable syntax support for TaggedExpr and RuleParam

Closed this issue · 2 comments

use std::{collections::HashMap, cell::RefCell};

peg::parser!(grammar parser() for str {
    pub rule keyvals() -> HashMap<&'input str, &'input str>
        = map:({ RefCell::new(HashMap::new()) })
        (k:$(['a'..='z']+) ":" v:$(['a'..='z']+) {
            map.borrow_mut().insert(k, v)
        })**","
        { map.into_inner() }
});

// Expect
//peg::parser!(grammar parser() for str {
//    pub rule keyvals() -> HashMap<&'input str, &'input str>
//        = mut map:({ HashMap::new() })
//        (k:$(['a'..='z']+) ":" v:$(['a'..='z']+) {
//            map.insert(k, v)
//        })**","
//        { map }
//});

Changing the state through repeated attempts at deduction may not be a good choice

Yes, mutability could be dangerous in the presence of backtracking.

For building a HashMap without allocating an intermediate Vec, it seems like there could be a trait that exposes new(), append(&mut self, elem: T) and maybe finish(self) that the generated code could use in place of Vec to collect the results of each iteration of a repeat operator. I am not sure what the syntax would look like to specify this type on a repeat operator.

Related to #294 (comment)