fn check_word_rule(&self, chars: &[char], input_rule: usize) -> Vec<usize> {
        if chars.is_empty() {
            return Vec::new();
        }

        match &self.rules[input_rule]
            .as_ref()
            .expect("the rule does not exist!")
        {
            Rule::Terminal(c) => {
                if &chars[0] == c {
                    vec![1]
                } else {
                    Vec::new()
                }
            }
            Rule::Nonterminal(rule) => {
                let mut used_by_subrules = Vec::new();

                for subrule in rule.subrules.iter() {
                    if subrule.len() > chars.len() {
                        // due to how substitutions work here, we must have at least n characters
                        // for n rules left
                        continue;
                    }
                    let mut subrule_consumed = vec![0];
                    for rule in subrule.iter() {
                        let mut new_thing = Vec::new();
                        for consumed in subrule_consumed {
                            let consumed_possibilities =
                                self.check_word_rule(&chars[consumed..], *rule);
                            if consumed_possibilities.is_empty() {
                                continue;
                            }
                            for consumed_pos in consumed_possibilities {
                                new_thing.push(consumed + consumed_pos)
                            }
                        }
                        subrule_consumed = new_thing;
                    }

                    // if we didn't consume anything, it means the subrule was invalid
                    if !subrule_consumed.is_empty() {
                        used_by_subrules.append(&mut subrule_consumed)
                    }
                }
                used_by_subrules
            }
        }
    }
// perform recursive descent parsing
// returns number of characters consumed by the rule on the word
perform recursive descent parsing
returns number of characters consumed by the rule on the word
perform recursive descent parsing returns number of characters consumed by the rule on the word
fn check_word_rule(&self, chars: &[char], input_rule: usize) -> Vec<usize> {
        if chars.is_empty() {
            return Vec::new();
        }
        match &self.rules[input_rule]
            .as_ref()
            .expect("the rule does not exist!")
        {
            Rule::Terminal(c) => {
                if &chars[0] == c {
                    vec![1]
                } else {
                    Vec::new()
                }
            }
            Rule::Nonterminal(rule) => {
                let mut used_by_subrules = Vec::new();
                for subrule in rule.subrules.iter() {
                    if subrule.len() > chars.len() {
                        // due to how substitutions work here, we must have at least n characters
                        // for n rules left
                        continue;
                    }
                    let mut subrule_consumed = vec![0];
                    for rule in subrule.iter() {
                        let mut new_thing = Vec::new();
                        for consumed in subrule_consumed {
                            let consumed_possibilities =
                                self.check_word_rule(&chars[consumed..], *rule);
                            if consumed_possibilities.is_empty() {
                                continue;
                            }
                            for consumed_pos in consumed_possibilities {
                                new_thing.push(consumed + consumed_pos)
                            }
                        }
                        subrule_consumed = new_thing;
                    }
                    // if we didn't consume anything, it means the subrule was invalid
                    if !subrule_consumed.is_empty() {
                        used_by_subrules.append(&mut subrule_consumed)
                    }
                }
                used_by_subrules
            }
        }
    }
fn check_word_rule ( & self , chars : & [ char ] , input_rule : usize ) -> Vec < usize > { if chars . is_empty ( ) { return Vec :: new ( ) ; } match & self . rules [ input_rule ] . as_ref ( ) . expect ( " " ) { Rule :: Terminal ( c ) => { if & chars [ 0 ] == c { vec ! [ 1 ] } else { Vec :: new ( ) } } Rule :: Nonterminal ( rule ) => { let mut used_by_subrules = Vec :: new ( ) ; for subrule in rule . subrules . iter ( ) { if subrule . len ( ) > chars . len ( ) { // due to how substitutions work here, we must have at least n characters // for n rules left continue ; } let mut subrule_consumed = vec ! [ 0 ] ; for rule in subrule . iter ( ) { let mut new_thing = Vec :: new ( ) ; for consumed in subrule_consumed { let consumed_possibilities = self . check_word_rule ( & chars [ consumed .. ] , * rule ) ; if consumed_possibilities . is_empty ( ) { continue ; } for consumed_pos in consumed_possibilities { new_thing . push ( consumed + consumed_pos ) } } subrule_consumed = new_thing ; } // if we didn't consume anything, it means the subrule was invalid if ! subrule_consumed . is_empty ( ) { used_by_subrules . append ( & mut subrule_consumed ) } } used_by_subrules } } }
perform recursive descent parsing
returns number of characters consumed by the rule on the word
perform recursive descent parsing returns number of characters consumed by the rule on the word
&self
chars
&[char]
input_rule
usize
&self
chars
&[char]
input_rule
usize