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 00025 class UnnecessaryNodeRemoverCopier : public indri::lang::Copier { 00026 protected: 00027 std::vector<indri::lang::Node*> _nodes; 00028 00029 class SingleChildWalker : public indri::lang::Walker { 00030 private: 00031 indri::lang::Node* _child; 00032 int _children; 00033 bool _seenRoot; 00034 00035 public: 00036 SingleChildWalker() : _seenRoot(false), _children(0), _child(0) {} 00037 00038 void defaultBefore( indri::lang::Node* n ) { 00039 if( !_seenRoot ) { 00040 _seenRoot = true; 00041 } else { 00042 _children++; 00043 _child = n; 00044 } 00045 } 00046 00047 bool onlyOneChild() { 00048 return _children == 1; 00049 } 00050 00051 indri::lang::Node* getChild() { 00052 return _child; 00053 } 00054 }; 00055 00056 public: 00057 ~UnnecessaryNodeRemoverCopier() { 00058 delete_vector_contents( _nodes ); 00059 } 00060 00061 indri::lang::Node* defaultAfter( indri::lang::Node* old, indri::lang::Node* newNode ) { 00062 _nodes.push_back( newNode ); 00063 return newNode; 00064 } 00065 00066 indri::lang::Node* after( indri::lang::ExtentAnd* oldAnd, indri::lang::ExtentAnd* newAnd ) { 00067 SingleChildWalker walker; 00068 newAnd->walk(walker); 00069 00070 if( walker.onlyOneChild() ) { 00071 delete newAnd; 00072 return walker.getChild(); 00073 } else { 00074 _nodes.push_back( newAnd ); 00075 return newAnd; 00076 } 00077 } 00078 00079 indri::lang::Node* after( indri::lang::ExtentOr* oldOr, indri::lang::ExtentOr* newOr ) { 00080 SingleChildWalker walker; 00081 newOr->walk(walker); 00082 00083 if( walker.onlyOneChild() ) { 00084 delete newOr; 00085 return walker.getChild(); 00086 } else { 00087 _nodes.push_back( newOr ); 00088 return newOr; 00089 } 00090 } 00091 00092 indri::lang::Node* after( indri::lang::ODNode* oldOD, indri::lang::ODNode* newOD ) { 00093 SingleChildWalker walker; 00094 newOD->walk(walker); 00095 00096 if( walker.onlyOneChild() ) { 00097 delete newOD; 00098 return walker.getChild(); 00099 } else { 00100 _nodes.push_back( newOD ); 00101 return newOD; 00102 } 00103 } 00104 00105 indri::lang::Node* after( indri::lang::UWNode* oldUW, indri::lang::UWNode* newUW ) { 00106 SingleChildWalker walker; 00107 newUW->walk(walker); 00108 00109 if( walker.onlyOneChild() ) { 00110 delete newUW; 00111 return walker.getChild(); 00112 } else { 00113 _nodes.push_back( newUW ); 00114 return newUW; 00115 } 00116 } 00117 }; 00118 00119 #endif // INDRI_UNNECESSARYNODEREMOVERCOPIER_HPP 00120