00001 /*========================================================================== 00002 * Copyright (c) 2004 University of Massachusetts. All Rights Reserved. 00003 * 00004 * Use of the Lemur Toolkit for Language Modeling and Information Retrieval 00005 * is subject to the terms of the software license set forth in the LICENSE 00006 * file included with this software, and also available at 00007 * http://www.lemurproject.org/license.html 00008 * 00009 *========================================================================== 00010 */ 00011 00012 00013 // 00014 // UnnecessaryNodeRemoverCopier 00015 // 00016 // 17 March 2004 -- tds 00017 // 00018 00019 #ifndef INDRI_UNNECESSARYNODEREMOVERCOPIER_HPP 00020 #define INDRI_UNNECESSARYNODEREMOVERCOPIER_HPP 00021 00022 #include "indri/QuerySpec.hpp" 00023 #include "indri/delete_range.hpp" 00024 namespace indri 00025 { 00026 namespace lang 00027 { 00028 00029 class UnnecessaryNodeRemoverCopier : public indri::lang::Copier { 00030 protected: 00031 std::vector<indri::lang::Node*> _nodes; 00032 00033 class SingleChildWalker : public indri::lang::Walker { 00034 private: 00035 indri::lang::Node* _child; 00036 int _children; 00037 bool _seenRoot; 00038 00039 public: 00040 SingleChildWalker() : _seenRoot(false), _children(0), _child(0) {} 00041 00042 void defaultBefore( indri::lang::Node* n ) { 00043 if( !_seenRoot ) { 00044 _seenRoot = true; 00045 } else { 00046 _children++; 00047 _child = n; 00048 } 00049 } 00050 00051 bool onlyOneChild() { 00052 return _children == 1; 00053 } 00054 00055 indri::lang::Node* getChild() { 00056 return _child; 00057 } 00058 }; 00059 00060 public: 00061 ~UnnecessaryNodeRemoverCopier() { 00062 indri::utility::delete_vector_contents( _nodes ); 00063 } 00064 00065 indri::lang::Node* defaultAfter( indri::lang::Node* old, indri::lang::Node* newNode ) { 00066 _nodes.push_back( newNode ); 00067 return newNode; 00068 } 00069 00070 indri::lang::Node* after( indri::lang::ExtentAnd* oldAnd, indri::lang::ExtentAnd* newAnd ) { 00071 SingleChildWalker walker; 00072 newAnd->walk(walker); 00073 00074 if( walker.onlyOneChild() ) { 00075 delete newAnd; 00076 return walker.getChild(); 00077 } else { 00078 _nodes.push_back( newAnd ); 00079 return newAnd; 00080 } 00081 } 00082 00083 indri::lang::Node* after( indri::lang::ExtentOr* oldOr, indri::lang::ExtentOr* newOr ) { 00084 SingleChildWalker walker; 00085 newOr->walk(walker); 00086 00087 if( walker.onlyOneChild() ) { 00088 delete newOr; 00089 return walker.getChild(); 00090 } else { 00091 _nodes.push_back( newOr ); 00092 return newOr; 00093 } 00094 } 00095 00096 indri::lang::Node* after( indri::lang::ODNode* oldOD, indri::lang::ODNode* newOD ) { 00097 SingleChildWalker walker; 00098 newOD->walk(walker); 00099 00100 if( walker.onlyOneChild() ) { 00101 delete newOD; 00102 return walker.getChild(); 00103 } else { 00104 _nodes.push_back( newOD ); 00105 return newOD; 00106 } 00107 } 00108 00109 indri::lang::Node* after( indri::lang::UWNode* oldUW, indri::lang::UWNode* newUW ) { 00110 SingleChildWalker walker; 00111 newUW->walk(walker); 00112 00113 if( walker.onlyOneChild() ) { 00114 delete newUW; 00115 return walker.getChild(); 00116 } else { 00117 _nodes.push_back( newUW ); 00118 return newUW; 00119 } 00120 } 00121 00122 indri::lang::Node* after( indri::lang::LengthPrior * oldLP, indri::lang::LengthPrior * newLP ) { 00123 if ( oldLP->getExponent() == 0 ) { 00124 indri::lang::Node* child = newLP->getChild(); 00125 delete newLP; 00126 return child; 00127 } else { 00128 _nodes.push_back( newLP ); 00129 return newLP; 00130 } 00131 } 00132 00133 }; 00134 } 00135 } 00136 00137 #endif // INDRI_UNNECESSARYNODEREMOVERCOPIER_HPP 00138