pub fn grep(&mut self, find: String) -> Vec<Match<S::ValueRef>> {
        let mut worklist = Vec::<(S::ValueRef, Option<String>)>::new();
        let mut bindings = HashMap::new();
        let mut seen_exprs = HashMap::new();
        let mut found = Vec::new();
        let first_expr = self.parse_expression(&find);
        for node in self.ssa.inorder_walk() {
            // First level of filtering.
            let nh = self.hash_data(node);
            if first_expr.current().as_ref().is_none()
                || first_expr.current().as_ref().unwrap() != &nh
            {
                continue;
            }
            {
                let args = self.ssa.operands_of(node);
                // All the cases which can cause a mismatch in the node and it's arguments.
                if args.len() != first_expr.len() {
                    continue;
                }
                worklist.clear();
                bindings.clear();
                for (i, argn) in args.iter().enumerate() {
                    worklist.push((*argn, first_expr.op(i + 1)));
                }
            }

            let mut viable = true;
            while let Some((inner_node, match_str)) = worklist.pop() {
                if match_str.is_none() {
                    // Mismatch
                    viable = false;
                    break;
                }
                let current_h = self.hash_data(inner_node);
                // Optimize by avoiding a regex match when an expression is already known/seen.
                let t = if let Some(tk) = seen_exprs.get(match_str.as_ref().unwrap()).cloned() {
                    tk
                } else {
                    let t_ = self.parse_expression(match_str.as_ref().unwrap());
                    seen_exprs.insert(match_str.unwrap(), t_.clone());
                    t_
                };

                if t.current().is_none() {
                    // Mismatch
                    viable = false;
                    break;
                }

                let current = t.current().unwrap();
                if current.starts_with('%') {
                    // Match the current subtree to the subtree bound by the variable before. If
                    // they do not match, then report as mismatch.
                    let subtreeh = self.hash_subtree(inner_node);
                    if let Some((old, _)) =
                        bindings.insert(current.clone(), (subtreeh.clone(), inner_node))
                    {
                        if old != subtreeh {
                            // Mismatch
                            viable = false;
                            break;
                        }
                    }
                } else if current_h != current {
                    // Mismatch
                    // No match case.
                    viable = false;
                    break;
                }

                let args = self.ssa.operands_of(inner_node);
                // All the cases which can cause a mismatch in the node and it's arguments.
                // Since "%" binds the entire subtree, it will not have any arguments. So we skip
                // this case.
                if args.len() != t.len() && !current.starts_with('%') {
                    viable = false;
                    break;
                }

                for (i, argn) in args.iter().enumerate() {
                    if i >= t.len() {
                        break;
                    };
                    worklist.push((*argn, t.op(i + 1)));
                }
            }

            if viable {
                let mut vbind = Vec::new();
                for (k, v) in &bindings {
                    vbind.push((k.clone(), v.1));
                }
                let nmatch = Match {
                    root: node,
                    bindings: vbind,
                };
                found.push(nmatch);
            }
        }
        found
    }
/// Returns the root of the subtree that matches the given `find` expression.
// TODO:
//   - Handle commutativity
Returns the root of the subtree that matches the given `find` expression.
TODO:
Handle commutativity
Returns the root of the subtree that matches the given ` find ` expression . TODO : Handle commutativity
pub fn grep(&mut self, find: String) -> Vec<Match<S::ValueRef>> {
        let mut worklist = Vec::<(S::ValueRef, Option<String>)>::new();
        let mut bindings = HashMap::new();
        let mut seen_exprs = HashMap::new();
        let mut found = Vec::new();
        let first_expr = self.parse_expression(&find);
        for node in self.ssa.inorder_walk() {
            // First level of filtering.
            let nh = self.hash_data(node);
            if first_expr.current().as_ref().is_none()
                || first_expr.current().as_ref().unwrap() != &nh
            {
                continue;
            }
            {
                let args = self.ssa.operands_of(node);
                // All the cases which can cause a mismatch in the node and it's arguments.
                if args.len() != first_expr.len() {
                    continue;
                }
                worklist.clear();
                bindings.clear();
                for (i, argn) in args.iter().enumerate() {
                    worklist.push((*argn, first_expr.op(i + 1)));
                }
            }
            let mut viable = true;
            while let Some((inner_node, match_str)) = worklist.pop() {
                if match_str.is_none() {
                    // Mismatch
                    viable = false;
                    break;
                }
                let current_h = self.hash_data(inner_node);
                // Optimize by avoiding a regex match when an expression is already known/seen.
                let t = if let Some(tk) = seen_exprs.get(match_str.as_ref().unwrap()).cloned() {
                    tk
                } else {
                    let t_ = self.parse_expression(match_str.as_ref().unwrap());
                    seen_exprs.insert(match_str.unwrap(), t_.clone());
                    t_
                };
                if t.current().is_none() {
                    // Mismatch
                    viable = false;
                    break;
                }
                let current = t.current().unwrap();
                if current.starts_with('%') {
                    // Match the current subtree to the subtree bound by the variable before. If
                    // they do not match, then report as mismatch.
                    let subtreeh = self.hash_subtree(inner_node);
                    if let Some((old, _)) =
                        bindings.insert(current.clone(), (subtreeh.clone(), inner_node))
                    {
                        if old != subtreeh {
                            // Mismatch
                            viable = false;
                            break;
                        }
                    }
                } else if current_h != current {
                    // Mismatch
                    // No match case.
                    viable = false;
                    break;
                }
                let args = self.ssa.operands_of(inner_node);
                // All the cases which can cause a mismatch in the node and it's arguments.
                // Since "%" binds the entire subtree, it will not have any arguments. So we skip
                // this case.
                if args.len() != t.len() && !current.starts_with('%') {
                    viable = false;
                    break;
                }
                for (i, argn) in args.iter().enumerate() {
                    if i >= t.len() {
                        break;
                    };
                    worklist.push((*argn, t.op(i + 1)));
                }
            }
            if viable {
                let mut vbind = Vec::new();
                for (k, v) in &bindings {
                    vbind.push((k.clone(), v.1));
                }
                let nmatch = Match {
                    root: node,
                    bindings: vbind,
                };
                found.push(nmatch);
            }
        }
        found
    }
pub fn grep ( & mut self , find : String ) -> Vec < Match < S :: ValueRef > > { let mut worklist = Vec :: < ( S :: ValueRef , Option < String > ) > :: new ( ) ; let mut bindings = HashMap :: new ( ) ; let mut seen_exprs = HashMap :: new ( ) ; let mut found = Vec :: new ( ) ; let first_expr = self . parse_expression ( & find ) ; for node in self . ssa . inorder_walk ( ) { // First level of filtering. let nh = self . hash_data ( node ) ; if first_expr . current ( ) . as_ref ( ) . is_none ( ) || first_expr . current ( ) . as_ref ( ) . unwrap ( ) != & nh { continue ; } { let args = self . ssa . operands_of ( node ) ; // All the cases which can cause a mismatch in the node and it's arguments. if args . len ( ) != first_expr . len ( ) { continue ; } worklist . clear ( ) ; bindings . clear ( ) ; for ( i , argn ) in args . iter ( ) . enumerate ( ) { worklist . push ( ( * argn , first_expr . op ( i + 1 ) ) ) ; } } let mut viable = true ; while let Some ( ( inner_node , match_str ) ) = worklist . pop ( ) { if match_str . is_none ( ) { // Mismatch viable = false ; break ; } let current_h = self . hash_data ( inner_node ) ; // Optimize by avoiding a regex match when an expression is already known/seen. let t = if let Some ( tk ) = seen_exprs . get ( match_str . as_ref ( ) . unwrap ( ) ) . cloned ( ) { tk } else { let t_ = self . parse_expression ( match_str . as_ref ( ) . unwrap ( ) ) ; seen_exprs . insert ( match_str . unwrap ( ) , t_ . clone ( ) ) ; t_ } ; if t . current ( ) . is_none ( ) { // Mismatch viable = false ; break ; } let current = t . current ( ) . unwrap ( ) ; if current . starts_with ( '%' ) { // Match the current subtree to the subtree bound by the variable before. If // they do not match, then report as mismatch. let subtreeh = self . hash_subtree ( inner_node ) ; if let Some ( ( old , _ ) ) = bindings . insert ( current . clone ( ) , ( subtreeh . clone ( ) , inner_node ) ) { if old != subtreeh { // Mismatch viable = false ; break ; } } } else if current_h != current { // Mismatch // No match case. viable = false ; break ; } let args = self . ssa . operands_of ( inner_node ) ; // All the cases which can cause a mismatch in the node and it's arguments. // Since "%" binds the entire subtree, it will not have any arguments. So we skip // this case. if args . len ( ) != t . len ( ) && ! current . starts_with ( '%' ) { viable = false ; break ; } for ( i , argn ) in args . iter ( ) . enumerate ( ) { if i >= t . len ( ) { break ; } ; worklist . push ( ( * argn , t . op ( i + 1 ) ) ) ; } } if viable { let mut vbind = Vec :: new ( ) ; for ( k , v ) in & bindings { vbind . push ( ( k . clone ( ) , v . 1 ) ) ; } let nmatch = Match { root : node , bindings : vbind , } ; found . push ( nmatch ) ; } } found }
Returns the root of the subtree that matches the given `find` expression.
Returns the root of the subtree that matches the given ` find ` expression .
&mut self
find
String
&mut self
find
String