예제 #1
0
bool cGraphMaster::isMatchWildcard(const InputIterator& input, const InputIterator& pattern, const unsigned long& rec) {
  if (input.isDone()) { if (pattern.isDone()) return true; else return false; }
  else {
    if (pattern.isDone()) return true;
    else {
      InputIterator input_copy(input);
      do { if (isMatch(input_copy, pattern, rec+1)) return true; input_copy++; } while(!input_copy.isDone());
      return false;
    }
  }
  return false;
}
예제 #2
0
bool cGraphMaster::getMatch(InputIterator input, NodeType curr_type, const NodeVec& tree, MatcherStruct& ms, unsigned long rec) {
  // save head of input and advance iterator
  string input_front = *input;
  input++;
    
   //cout<<"tree.front().key="<<tree.front().key<<endl;

  _DBG_CODE(msg_dbg() << "[" << rec << "]getMatch(" << curr_type << ") HEAD: [" << input_front << "] last input?:" << boolalpha << input.isDone() << endl);
  
  /** FIRST WILDCARD: try to match the '_' wildcard **/
  if (tree.front().key == "_") {
    _DBG_CODE(msg_dbg() << "[" << rec << "]" << "Looking in '_'" << endl);
    if (getMatchWildcard(input, curr_type, tree.front(), ms, rec, input_front)) { if (ms.log) ms.logMatch("_", curr_type); return true; }
  }
  
  /** KEYS: if wildcard didn't matched, look for specific matching keys against current input_front **/
  _DBG_CODE(msg_dbg() << "[" << rec << "]" << "KEYS" << endl);
  Node tmp_node;
  tmp_node.key = input_front;
  NodeVec::const_iterator it = lower_bound(tree.begin(), tree.end(), tmp_node);
  // if there was a match
  if (it != tree.end() && it->key == input_front) {
    // if there are more tokens on input
    if (!input.isDone()) {
      // if I have something to match with, then look for a match
      if (!it->same_childs.empty()) {
        if (getMatch(input, curr_type, it->same_childs, ms, rec+1)) { if (ms.log) ms.logMatch(it->key, curr_type); return true; }
      }
    }
    // else, this is the last token
    else {
      // get the the next type of nodes to match if necessary
      list<string> match_list;
      if (curr_type != NODE_TOPIC && !it->diff_childs.empty()) ms.user.getMatchList(NodeType(curr_type+1), match_list);

      // if in previous situation check if there's a match deeper
      if (curr_type != NODE_TOPIC && !it->diff_childs.empty() &&
          getMatch(match_list, nextNodeType(curr_type), it->diff_childs, ms, rec+1))
      {
        if (ms.log) ms.logMatch(it->key, curr_type); return true;
      }
      // if I'm in the final type of nodes, it needs to be a leaf to have a match
      else if (curr_type == NODE_TOPIC && !it->templ.empty()) {
        ms.templ = it->templ;
        if (ms.log) ms.logMatch(it->key, curr_type);
        return true;
      }
    }
  }

  /** LAST WILDCARD: if above didn't matched repeat procedure for '_' **/
  if (tree.back().key == "*") {
    _DBG_CODE(msg_dbg() << "[" << rec << "]" << "Looking in '*'" << endl);
    if (getMatchWildcard(input, curr_type, tree.back(), ms, rec, input_front)) { if (ms.log) ms.logMatch("*", curr_type); return true; }
  }
  
  return false;
}
예제 #3
0
// Reduced version of the matching algorithm found on graphmaster.cpp, look there for a thorough explanation of the code
// This version doesn't have to handle with different node types. The pattern is just a list, not a tree, so it is much easier
bool cGraphMaster::isMatch(InputIterator input, InputIterator pattern, unsigned long rec) {
  string input_head(*input);
  string patt_head(*pattern);
  input++; pattern++;

  if (patt_head == "_" && isMatchWildcard(input, pattern, rec)) return true;
  
  if (patt_head == input_head) {
    if (input.isDone()) { if (pattern.isDone()) return true; else return false; }
    else {
      if (pattern.isDone()) return false;
      else {
        if (isMatch(input, pattern, rec+1)) return true;
        else return false;
      }
    }
  }

  if (patt_head == "*" && isMatchWildcard(input, pattern, rec)) return true;
  
  return false;
}
예제 #4
0
bool cGraphMaster::getMatchWildcard(const InputIterator& input, const NodeType& curr_type, const Node& tree_frontback, MatcherStruct& ms, const unsigned long& rec, const string& input_front) {
  // add the head token to the <*star/>, will remove it if it didn't matched later
  StarIt it = ms.sh.AddStar(input_front, curr_type);

  // if this is not the last token of input
  if (!input.isDone()) {
    // if this is the last node of the path, then it is a match (save the star and then proceed to match the next node type)
    if (tree_frontback.same_childs.empty()) {
      for (InputIterator input_copy(input); !input_copy.isDone(); input_copy++) *it += string(" ") + *input_copy;
    }
    // it isn't, so try matching this token with the wildcard and match the rest in a deeper recursion,
    // after that start making a bigger match for current wildcard, until all trailing input is matched against this wildcard
    else {
      InputIterator input_copy(input);
      do {
        if (getMatch(input_copy, curr_type, tree_frontback.same_childs, ms, rec+1)) return true;
        *it += string(" ") + *input_copy; input_copy++;
      } while(!input_copy.isDone());
    }
  }

  // this is reached if the match is in this recursion level (the deepest level will set the template and return true,
  // so I don't have to do anything but pass the 'true' if getMatch() returns true)
  // This situation is because either:
  //  a) one token of input (sure match, I have to continue the matching job deeper)
  //  b) more than one token of input and:
  //    b.1) trailing wildcard (sure match, eats all available input)
  //    b.2) the wildcard couldn't be used to match just a part of the trailing input, so it matches ALL the trailing input

  // if i'm not in the final type (ie: not matching the topic) of node and there are other type of nodes I
  // should get the next type of nodes to match
  list<string> match_list;
  if (curr_type != NODE_TOPIC && !tree_frontback.diff_childs.empty())
    ms.user.getMatchList(NodeType(curr_type+1), match_list);

  // so, If I'm in the previous situation AND there's a match with the current match list I should return 'there is a match'
  if (curr_type != NODE_TOPIC && !tree_frontback.diff_childs.empty() &&
       getMatch(match_list, nextNodeType(curr_type), tree_frontback.diff_childs, ms, rec+1)) return true;

  // if not, I need to see if I'm matching the topic AND I reached a possible leaf, if so I'm all done, set the template
  else if (curr_type == NODE_TOPIC && !tree_frontback.templ.empty()) { ms.templ = tree_frontback.templ; return true; }

  // If I reach here, then there was no match anywere, so I remove the previously added token from <*star>
  ms.sh.DelStar(it, curr_type);
  return false;
}