if_diff/src/idfMatchAst.cxx
//============================================================================
// match_ast
//----------------------------------------------------------------------------
// Match nodes between AST trees.
// Call this when ast1 ought to match ast2 and is expected to do so.
// If minor differences between the 2 nodes exist, they will be matched
// anyway.
//============================================================================
match_ast
Match nodes between AST trees.
Call this when ast1 ought to match ast2 and is expected to do so.
If minor differences between the 2 nodes exist, they will be matched
anyway.
match_ast Match nodes between AST trees . Call this when ast1 ought to match ast2 and is expected to do so . If minor differences between the 2 nodes exist they will be matched anyway .
static boolean match_ast(idfAst *ast1, idfAst *ast2, 
	                 const idfModel &model1, const idfModel &model2,
      	      	      	 boolean *matched_among_children)
{
  boolean mac;
  boolean &child_matched = matched_among_children != NULL ? *matched_among_children : mac;
  child_matched = false;
  if (ast1 == NULL || ast2 == NULL) {
#if defined(IDF_DEBUG)
    cout << "match_ast failed due to null operand" << endl;
#endif
    return false;
  }
  if (ast1->getMatch() != NULL && ast2->getMatch() != NULL) {
#if defined(IDF_DEBUG)
    cout << "match_ast decided on basis of previous match" << endl;
#endif
    return child_matched = ast1->getMatch() == ast2 || ast2->getMatch() == ast1;
  }
  int goodness, badness, locness, higher;
#if defined(IDF_DEBUG)
  genString node1str;
  id_string(ast1, node1str);
  genString node2str;
  id_string(ast2, node2str);
  cout << "attempting to match " << node1str << " to " << node2str << "." << endl;
#endif
  try_match(ast1, ast2, model1, model2, goodness, badness, locness, higher);
#if defined(IDF_DEBUG)
  cout << "match_ast found goodness " << goodness
       << " badness " << badness
       << " locness " << locness << "." << endl;
#endif
  int this_good = goodness - badness;
  idfAst *use1 = ast1;
  idfAst *use2 = ast2;
  const int threshold = 4;
  if (locness >= 0) {
    const int exceed = 5;
    if (ast1->getNumChildren() == 1) {
      try_match(ast1->getChild(0), ast2, model1, model2, goodness, badness, locness, higher);
      if (goodness - badness > threshold && goodness - badness > this_good + exceed) {
      	use1 = ast1->getChild(0);
      	this_good = goodness - badness;
      }
    }
    if (use1 == ast1 && ast2->getNumChildren() == 1) {
      try_match(ast1, ast2->getChild(0), model1, model2, goodness, badness, locness, higher);
      if (goodness - badness > threshold && goodness - badness > this_good + exceed) {
      	use2 = ast2->getChild(0);
      	this_good = goodness - badness;
      }
    }
  }
  if (this_good > threshold) {
    set_match(*use1, *use2, model1, model2, true);
    return child_matched = true; 
  }
  else {
    const char *kind1 = ast1->getKind();
    const char *kind2 = ast2->getKind();
    if (kind1 != NULL && kind2 != NULL && is_kind_within(kind2, kind1)) {
      child_matched = match_children_to(*ast1, *ast2, model1, model2);
    }
    else if (kind1 != NULL && kind2 != NULL && is_kind_within(kind1, kind2)) {
      child_matched = match_to_children(*ast1, *ast2, model1, model2);
    }
    else {
      locationStruct loc1;
      locationStruct loc2;
      if (get_location(ast1, loc1) && get_location(ast2, loc2)) {
	if (locations_overlap(loc1, loc2)) {
	  if (location_contains(loc1, loc2)) {
	    child_matched = match_children_to(*ast1, *ast2, model1, model2);
	    if (!child_matched) {
	      child_matched = match_to_children(*ast1, *ast2, model1, model2);
	    }
	  }
	  else if (location_contains(loc2, loc1)) {
	    child_matched = match_to_children(*ast1, *ast2, model1, model2);
	    if (!child_matched) {
	      child_matched = match_children_to(*ast1, *ast2, model1, model2);
	    }
	  }
	  else {
	    child_matched = match_children(ast1->getChildren(), ast2->getChildren(), model1, model2);
	  }
	}
      }
    }
#if defined(IDF_DEBUG)
    cout << "match_ast of " << node1str << " to " << node2str << " "
         << (child_matched ? "found" : "did not find") << " a match among children." << endl;
#endif
    idfStringSet *ssp = idf_configuration.lookup("AST nodes () should be revisited.");
    if (   ast1->getMatch() == NULL && ast2->getMatch() == NULL
        && (   child_matched 
            || (   idf_strmatch(ast1->getKind(), ast2->getKind()) 
                && ssp != NULL && ssp->contains(ast1->getKind())
               )
           )
       ) {
      try_match(ast1, ast2, model1, model2, goodness, badness, locness, higher, true);
#if defined(IDF_DEBUG)
      cout << "match_ast found goodness " << goodness
           << " badness " << badness
           << " locness " << locness << " when revisiting." << endl;
#endif
      if (goodness - badness > threshold) {
        set_match(*ast1, *ast2, model1, model2, true);
        return child_matched = true;
      }
    }
  }
  return false;
}
static boolean match_ast ( idfAst * ast1 , idfAst * ast2 , const idfModel & model1 , const idfModel & model2 , boolean * matched_among_children ) { boolean mac ; boolean & child_matched = matched_among_children != NULL ? * matched_among_children : mac ; child_matched = false ; if ( ast1 == NULL || ast2 == NULL ) { #if defined ( IDF_DEBUG ) cout << " " << endl ; #endif return false ; } if ( ast1 -> getMatch ( ) != NULL && ast2 -> getMatch ( ) != NULL ) { #if defined ( IDF_DEBUG ) cout << " " << endl ; #endif return child_matched = ast1 -> getMatch ( ) == ast2 || ast2 -> getMatch ( ) == ast1 ; } int goodness , badness , locness , higher ; #if defined ( IDF_DEBUG ) genString node1str ; id_string ( ast1 , node1str ) ; genString node2str ; id_string ( ast2 , node2str ) ; cout << " " << node1str << " " << node2str << " " << endl ; #endif try_match ( ast1 , ast2 , model1 , model2 , goodness , badness , locness , higher ) ; #if defined ( IDF_DEBUG ) cout << " " << goodness << " " << badness << " " << locness << " " << endl ; #endif int this_good = goodness - badness ; idfAst * use1 = ast1 ; idfAst * use2 = ast2 ; const int threshold = 4 ; if ( locness >= 0 ) { const int exceed = 5 ; if ( ast1 -> getNumChildren ( ) == 1 ) { try_match ( ast1 -> getChild ( 0 ) , ast2 , model1 , model2 , goodness , badness , locness , higher ) ; if ( goodness - badness > threshold && goodness - badness > this_good + exceed ) { use1 = ast1 -> getChild ( 0 ) ; this_good = goodness - badness ; } } if ( use1 == ast1 && ast2 -> getNumChildren ( ) == 1 ) { try_match ( ast1 , ast2 -> getChild ( 0 ) , model1 , model2 , goodness , badness , locness , higher ) ; if ( goodness - badness > threshold && goodness - badness > this_good + exceed ) { use2 = ast2 -> getChild ( 0 ) ; this_good = goodness - badness ; } } } if ( this_good > threshold ) { set_match ( * use1 , * use2 , model1 , model2 , true ) ; return child_matched = true ; } else { const char * kind1 = ast1 -> getKind ( ) ; const char * kind2 = ast2 -> getKind ( ) ; if ( kind1 != NULL && kind2 != NULL && is_kind_within ( kind2 , kind1 ) ) { child_matched = match_children_to ( * ast1 , * ast2 , model1 , model2 ) ; } else if ( kind1 != NULL && kind2 != NULL && is_kind_within ( kind1 , kind2 ) ) { child_matched = match_to_children ( * ast1 , * ast2 , model1 , model2 ) ; } else { locationStruct loc1 ; locationStruct loc2 ; if ( get_location ( ast1 , loc1 ) && get_location ( ast2 , loc2 ) ) { if ( locations_overlap ( loc1 , loc2 ) ) { if ( location_contains ( loc1 , loc2 ) ) { child_matched = match_children_to ( * ast1 , * ast2 , model1 , model2 ) ; if ( ! child_matched ) { child_matched = match_to_children ( * ast1 , * ast2 , model1 , model2 ) ; } } else if ( location_contains ( loc2 , loc1 ) ) { child_matched = match_to_children ( * ast1 , * ast2 , model1 , model2 ) ; if ( ! child_matched ) { child_matched = match_children_to ( * ast1 , * ast2 , model1 , model2 ) ; } } else { child_matched = match_children ( ast1 -> getChildren ( ) , ast2 -> getChildren ( ) , model1 , model2 ) ; } } } } #if defined ( IDF_DEBUG ) cout << " " << node1str << " " << node2str << " " << ( child_matched ? " " : " " ) << " " << endl ; #endif idfStringSet * ssp = idf_configuration . lookup ( " " ) ; if ( ast1 -> getMatch ( ) == NULL && ast2 -> getMatch ( ) == NULL && ( child_matched || ( idf_strmatch ( ast1 -> getKind ( ) , ast2 -> getKind ( ) ) && ssp != NULL && ssp -> contains ( ast1 -> getKind ( ) ) ) ) ) { try_match ( ast1 , ast2 , model1 , model2 , goodness , badness , locness , higher , true ) ; #if defined ( IDF_DEBUG ) cout << " " << goodness << " " << badness << " " << locness << " " << endl ; #endif if ( goodness - badness > threshold ) { set_match ( * ast1 , * ast2 , model1 , model2 , true ) ; return child_matched = true ; } } } return false ; }
match_ast
Match nodes between AST trees.
match_ast Match nodes between AST trees .
// Try child down 1 level in case child matches better. // !! assignment intentional // This is not a match. But try for a match among children. // Try for a match among children, based on location. // Locations exist for both nodes. // If there is overlap, continue the comparison. // Revisit the possibility of a match at this level.