メインページ | ネームスペース一覧 | クラス階層 | 構成 | Directories | ファイル一覧 | ネームスペースメンバ | 構成メンバ | ファイルメンバ | 関連ページ

FITreeConverter.h

00001 #ifndef FI_TREE_CONVERTER_H
00002 #define FI_TREE_CONVERTER_H
00003 //---------------------------------------------------------------------------
00004 //木構造から木構造への変換器(FIHalfTreeConverter)と、
00005 //その変換ルールを記述するための各種パターン(FIPattern)。
00006 //---------------------------------------------------------------------------
00007 #include <utility>
00008 #include <map>
00009 #include <list>
00010 #include <vector>
00011 #include <boost/shared_ptr.hpp>
00012 #include <boost/spirit/core.hpp>
00013 #include <boost/spirit/tree/parse_tree.hpp>
00014 //---------------------------------------------------------------------------
00015 //ラベル付きノード列の種類
00016 enum FILabeledType{
00017     filtNodes,//更なるマッチングの対象になるノード列
00018     filtValue//これ以上マッチングせず、値として扱う
00019 };
00020 
00021 //---------------------------------------------------------------------------
00022 //木の変換で必要な、型の組み合わせごとに独自の定義が必要な操作の集合
00023 //(特殊化して使う)
00024 template <class TL, class TR>
00025 struct FIConvertationTraits;
00026 //---------------------------------------------------------------------------
00027 //木変換系のクラスで共通に使う定義集(継承して使う)
00028 template <class TTraits>
00029 class FITreeDefs
00030 {
00031 public:
00032     //属性のキーの型。
00033     typedef typename TTraits::TKey TKey;
00034     //文字列の型。
00035     typedef typename TTraits::TString TString;
00036 
00037   //ノードの型(入力側)。
00038     typedef typename TTraits::TInNode TInNode;
00039   //値の型(入力側)。
00040     typedef typename TTraits::TInValue TInValue;
00041   //属性の型(入力側)。
00042     typedef typename TTraits::TInAttribute TInAttribute;
00043     //ノードの各属性を舐めるイテレータ。
00044     typedef typename TTraits::TInIterator TInIterator;
00045 
00046     //属性のキー。
00047     static TKey GetKey(const TInAttribute& attr){
00048         return TTraits::GetKey(attr);
00049     }
00050   //属性の値。
00051     static TInValue GetValue(const TInAttribute& attr){
00052         return TTraits::GetValue(attr);
00053     }
00054   //値が文字列ならtrue、ノードならfalse。
00055     static bool IsString(const TInValue& value){
00056         return TTraits::IsString(value);
00057     }
00058     //値の文字列。
00059     static TString GetString(const TInValue& value){
00060         return TTraits::GetString(value);
00061     }
00062   //値のノード。
00063     static TInNode GetNode(const TInValue& value){
00064         return TTraits::GetNode(value);
00065     }
00066     //子ノードの先頭を取得
00067     static TInIterator GetBegin(const TInNode& node){
00068         return TTraits::GetBegin(node);
00069     }
00070     //子ノードの末尾の次を取得
00071     static TInIterator GetEnd(const TInNode& node){
00072         return TTraits::GetEnd(node);
00073     }
00074   //iが指す属性。
00075     static TInAttribute GetAttribute(const TInNode& node, TInIterator i){
00076         return TTraits::GetAttribute(node, i);
00077     }
00078 
00079   //ノードの型(出力側)。
00080     typedef typename TTraits::TOutNode TOutNode;
00081   //値の型(出力側)。
00082   typedef typename TTraits::TOutValue TOutValue;
00083     //属性の型(出力側)。
00084     typedef typename TTraits::TOutAttribute TOutAttribute;
00085     //属性列の型(出力側)。
00086     typedef typename TTraits::TOutAttributes TOutAttributes;
00087 
00088   //ノードを作る。
00089     static void CreateNode(TOutNode& node, const TOutAttributes& attrs){
00090         TTraits::CreateNode(node, attrs);
00091     }
00092   //文字列を持つ値を作る。
00093   static void CreateValue(TOutValue& value, const TString& s){
00094         TTraits::CreateValue(value, s);
00095     }
00096   //ノードを持つ値を作る。
00097   static void CreateValue(TOutValue& value, const TOutNode& node){
00098         TTraits::CreateValue(value, node);
00099     }
00100   //属性を作る。
00101   static void CreateAttribute(TOutAttribute& attr, const TKey& key, const TOutValue& value){
00102         TTraits::CreateAttribute(attr, key, value);
00103     }
00104   //属性列の末尾に属性を追加する。
00105   static void Add(TOutAttributes& attrs, const TOutAttribute& attr){
00106         TTraits::Add(attrs, attr);
00107     }
00108   //属性列の末尾に属性列を追加する。
00109   static void Add(TOutAttributes& attrs, const TOutAttributes& added){
00110         TTraits::Add(attrs, added);
00111     }
00112 
00113     //ラベルを付けられたノード列の情報
00114     struct TLabeledInfo{
00115         TInNode node;//ノード
00116         TInIterator first;//ノード列の先頭
00117         TInIterator last;//ノード列の末尾の次
00118         TLabeledInfo(){}
00119         TLabeledInfo(const TInNode& n, TInIterator f, TInIterator l)
00120             : node(n), first(f), last(l){}
00121     };
00122     //値の配列(出力側)。
00123     typedef std::vector<TOutValue> TOutValues;
00124 
00125     //ノード列マッチング中に、ラベルに対応する値列を記録するためのマップ。
00126     typedef std::map<int, TLabeledInfo> TSourceLabelMap;
00127     struct TSourceLabelMaps{
00128         TSourceLabelMap values;
00129         TSourceLabelMap attrs;
00130     };
00131     //ノード列生成時に、ラベルに対応する値列を与えるためのマップ。
00132     typedef std::map<int, TOutValues> TTargetValueLabelMap;
00133     typedef std::map<int, TOutAttributes> TTargetAttributeLabelMap;
00134     struct TTargetLabelMaps{
00135         TTargetValueLabelMap values;
00136         TTargetAttributeLabelMap attrs;
00137     };
00138 
00139 };
00140 //---------------------------------------------------------------------------
00141 //木のパターンの実装の基底クラス
00142 template <class TTraits>
00143 class FIPatternImpl: public FITreeDefs<TTraits>
00144 {
00145 public:
00146     FIPatternImpl(): label(0){}
00147     virtual ~FIPatternImpl(){}
00148     //ノード列がパターンにマッチするかを調べる
00149     virtual std::pair<bool, TInIterator>
00150         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap)= 0;
00151     //パターンを雛型として属性列を作り、attrsに追加する。
00152     //自分にラベルが付いていたら、ラベルに対応する属性列を返す。
00153     void Generate(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00154     //ラベルを付ける
00155     void SetLabel(int l){ label= l; }
00156     //ラベルが付いていたら、それをlmapに記録する
00157     void SaveIfLabeled(
00158         const TInNode& node, 
00159         TInIterator first, 
00160         TInIterator last, 
00161         TSourceLabelMaps* lmap,
00162         bool asAttrs= false);
00163     //マッチする属性のキー。
00164     virtual TKey GetMatchingKey()const= 0;
00165     virtual void SetMatchingKey(const TKey& k)= 0;
00166 
00167 protected:
00168     //パターンを元に属性列を作り、attrsに追加する。
00169     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap)= 0;
00170     //ラベルに対応する属性列を作り、attrsに追加する。
00171     virtual void GenerateLabeled(
00172         TOutAttributes& attrs, const TOutValues& values);
00173 
00174 private:
00175     int label;//ラベル
00176 
00177 };
00178 //---------------------------------------------------------------------------
00179 //木のパターン
00180 //(値として扱えるようにFIPatternImplをラップしている)
00181 template <class TTraits>
00182 class FIPattern: public FITreeDefs<TTraits>
00183 {
00184 public:
00185     explicit FIPattern(FIPatternImpl<TTraits>* i): impl(i){}
00186     //ノード列がパターンにマッチするかを調べる
00187     std::pair<bool, TInIterator> Match(
00188         const TInNode& pnode, 
00189         TInIterator first, 
00190         TInIterator last, 
00191         TSourceLabelMaps* lmap)const{
00192             return impl->Match(pnode, first, last, lmap);
00193     }
00194     //パターンを雛型として属性列を作り、attrsに追加する。
00195     //自分にラベルが付いていたら、ラベルに対応する属性列を返す。
00196     void Generate(TOutAttributes& attrs, const TTargetLabelMaps* lmap)const{
00197         impl->Generate(attrs, lmap);
00198     }
00199     //ラベルを付ける
00200     FIPattern& operator[](int l){
00201         impl->SetLabel(l);
00202         return *this;
00203     }
00204     //自身をFIOptionalPatternImplでくるんで返す
00205     FIPattern operator!();
00206     //実装
00207     boost::shared_ptr<FIPatternImpl<TTraits> > GetImpl()const{ return impl; }
00208 
00209 private:
00210     boost::shared_ptr<FIPatternImpl<TTraits> > impl;//実装
00211 
00212 };
00213 //---------------------------------------------------------------------------
00214 //パターンをつなげる
00215 template <class T>
00216 inline FIPattern<T> operator>>(
00217   const FIPattern<T>& firstPattern, const FIPattern<T>& secondPattern);
00218 //---------------------------------------------------------------------------
00219 //単独のノードを持つ属性を表すパターン
00220 template <class TTraits>
00221 class FINodePatternImpl: public FIPatternImpl<TTraits>
00222 {
00223 public:
00224     //名前と子ノード列のパターンを指定する
00225     FINodePatternImpl(const TKey& k, const FIPattern<TTraits>& p)
00226         : key(k), childrenPattern(p){}
00227     //ノード列がパターンにマッチするかを調べる
00228     virtual std::pair<bool, TInIterator>
00229         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap);
00230 
00231 protected:
00232     //パターンを元に属性列を作り、attrsに追加する。
00233     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00234     //マッチする属性のキー。
00235     virtual TKey GetMatchingKey()const{ return key; }
00236     virtual void SetMatchingKey(const TKey& k);
00237 
00238 private:
00239     TKey key;//マッチする属性のキー
00240     FIPattern<TTraits> childrenPattern;//子ノード列のパターン
00241 
00242 };
00243 //---------------------------------------------------------------------------
00244 //単独の文字列を持つ属性を表すパターン
00245 template <class TTraits>
00246 class FIStringPatternImpl: public FIPatternImpl<TTraits>
00247 {
00248 public:
00249     FIStringPatternImpl(const TKey& k, const TString& v)
00250         : key(k), str(v){}
00251     //ノード列がパターンにマッチするかを調べる
00252     virtual std::pair<bool, TInIterator>
00253         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap);
00254 
00255 protected:
00256     //パターンを元に属性列を作り、attrsに追加する。
00257     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00258     //マッチする属性のキー。
00259     virtual TKey GetMatchingKey()const{ return key; }
00260     virtual void SetMatchingKey(const TKey& k);
00261 
00262 private:
00263     TKey key;//マッチする属性のキー
00264     TString str;//文字列
00265 
00266 };
00267 //---------------------------------------------------------------------------
00268 //任意の値を持つ属性を表すパターン
00269 template <class TTraits>
00270 class FIAnyValuePatternImpl: public FIPatternImpl<TTraits>
00271 {
00272 public:
00273     FIAnyValuePatternImpl(const TKey& k)
00274         : key(k){}
00275     //ノード列がパターンにマッチするかを調べる
00276     virtual std::pair<bool, TInIterator>
00277         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap);
00278 
00279 protected:
00280     //パターンを元に属性列を作り、attrsに追加する。
00281     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00282     //マッチする属性のキー。
00283     virtual TKey GetMatchingKey()const{ return key; }
00284     virtual void SetMatchingKey(const TKey& k){ key= k; }
00285 
00286 private:
00287     TKey key;//マッチする属性のキー
00288 
00289 };
00290 //---------------------------------------------------------------------------
00291 //パターンのつながり
00292 //(記述時には >> で表現する)
00293 template <class TTraits>
00294 class FIConjunctionPatternImpl: public FIPatternImpl<TTraits>
00295 {
00296 public:
00297     FIConjunctionPatternImpl(const FIPattern<TTraits>& f, const FIPattern<TTraits>& s)
00298         : firstPattern(f), secondPattern(s){}
00299     //ノード列がパターンにマッチするかを調べる
00300     virtual std::pair<bool, TInIterator>
00301         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap);
00302 
00303 protected:
00304     //パターンを元に属性列を作り、attrsに追加する。
00305     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00306     //マッチする属性のキー。
00307     virtual TKey GetMatchingKey()const;
00308     virtual void SetMatchingKey(const TKey& k);
00309 
00310 private:
00311     FIPattern<TTraits> firstPattern;//1つ目のパターン
00312     FIPattern<TTraits> secondPattern;//2つ目のパターン
00313 
00314 };
00315 //---------------------------------------------------------------------------
00316 //省略可能を表すパターン
00317 //(記述時には ! で表現する)
00318 template <class TTraits>
00319 class FIOptionalPatternImpl: public FIPatternImpl<TTraits>
00320 {
00321 public:
00322     FIOptionalPatternImpl(const FIPattern<TTraits>& p)
00323         : pattern(p){}
00324     //ノード列がパターンにマッチするかを調べる
00325     virtual std::pair<bool, TInIterator>
00326         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap);
00327 
00328 protected:
00329     //パターンを元に属性列を作り、attrsに追加する。
00330     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00331     //マッチする属性のキー。
00332     virtual TKey GetMatchingKey()const;
00333     virtual void SetMatchingKey(const TKey& k);
00334 
00335 private:
00336     FIPattern<TTraits> pattern;//内包するパターン
00337 
00338 };
00339 //---------------------------------------------------------------------------
00340 //任意の値を持つ複数の属性にマッチするパターン
00341 template <class TTraits>
00342 class FIAnyPatternImpl: public FIPatternImpl<TTraits>
00343 {
00344 public:
00345     FIAnyPatternImpl(const TKey& k)
00346         : key(k){}
00347     //ノード列がパターンにマッチするかを調べる
00348     virtual std::pair<bool, TInIterator>
00349         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap);
00350     //マッチする属性のキー。
00351     virtual TKey GetMatchingKey()const{ return key; }
00352     virtual void SetMatchingKey(const TKey& k){ key= k; }
00353 
00354 protected:
00355     //パターンを元に属性列を作り、attrsに追加する。
00356     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00357 
00358 private:
00359     TKey key;//マッチする属性のキー
00360 
00361 };
00362 //---------------------------------------------------------------------------
00363 //任意の属性にマッチするパターン。
00364 //ラベルが値列ではなく属性列にマッチする。
00365 template <class TTraits>
00366 class FIAnyAttributesPatternImpl: public FIPatternImpl<TTraits>
00367 {
00368 public:
00369     //ノード列がパターンにマッチするかを調べる
00370     virtual std::pair<bool, TInIterator>
00371         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap);
00372     //マッチする属性のキー。
00373     virtual TKey GetMatchingKey()const{ assert(false); return TKey(); }
00374     virtual void SetMatchingKey(const TKey& k){ assert(false); }
00375 
00376 protected:
00377     //パターンを元に属性列を作り、attrsに追加する。
00378     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00379 
00380 };
00381 
00382 //---------------------------------------------------------------------------
00383 //任意の属性にマッチするパターン。
00384 //ラベルが値列ではなく属性列にマッチする。
00385 template <class TTraits>
00386 class FIAASPatternImpl: public FIPatternImpl<TTraits>
00387 {
00388     FIPattern<TTraits> end;
00389 public:
00390     FIAASPatternImpl(const FIPattern<TTraits>& e):end(e){
00391     }
00392     //ノード列がパターンにマッチするかを調べる
00393     virtual std::pair<bool, TInIterator>
00394         Match(const TInNode& pnode, TInIterator first, TInIterator last, TSourceLabelMaps* lmap);
00395     //マッチする属性のキー。
00396     virtual TKey GetMatchingKey()const{ assert(false); return TKey(); }
00397     virtual void SetMatchingKey(const TKey& k){ assert(false); }
00398 
00399 protected:
00400     //パターンを元に属性列を作り、attrsに追加する。
00401     virtual void GenerateSelf(TOutAttributes& attrs, const TTargetLabelMaps* lmap);
00402 };
00403 //---------------------------------------------------------------------------
00404 //木のパターンの定義を集めたもの
00405 template <class TTraits>
00406 struct FITreePatterns: public FITreeDefs<TTraits>
00407 {
00408     //パターン
00409     typedef FIPattern<TTraits> TPattern;
00410 
00411     //任意ノード列
00412     static TPattern Any(){
00413         return TPattern(new FIAnyPatternImpl<TTraits>(TKey()));
00414     }
00415     //ノード
00416     static TPattern Node(const TPattern& childrenPattern){
00417         return TPattern(new FINodePatternImpl<TTraits>(TKey(), childrenPattern));
00418     }
00419     //任意の値
00420     static TPattern Value(){
00421         return TPattern(new FIAnyValuePatternImpl<TTraits>(TKey()));
00422     }
00423     //文字列
00424     static TPattern String(const TString& str){
00425         return TPattern(new FIStringPatternImpl<TTraits>(TKey(), str));
00426     }
00427     //属性化
00428     static TPattern Attribute(const TKey& key, const TPattern& pattern){
00429         pattern.GetImpl()->SetMatchingKey(key);
00430         return pattern;
00431     }
00432     //任意属性列
00433     static TPattern AnyAttributes(){
00434         return TPattern(new FIAnyAttributesPatternImpl<TTraits>());
00435     }
00436     static TPattern AAS(TPattern& p){
00437         return TPattern(new FIAASPatternImpl<TTraits>(p));
00438     }
00439 
00440 };
00441 //---------------------------------------------------------------------------
00442 //片方向(TLTraits→TRTraits)の木変換器
00443 template <class TLTraits, class TRTraits>
00444 class FIHalfTreeConverter
00445 {
00446     typedef FIHalfTreeConverter TThis;
00447     typedef FITreePatterns<TLTraits> TL;
00448     typedef FITreePatterns<TRTraits> TR;
00449 
00450 public:
00451     //ルールを追加
00452     void Add(
00453         const typename TL::TPattern& lpattern, 
00454         const typename TR::TPattern& rpattern);
00455     //parentが持つ[first,last)の範囲の属性列を変換し、その結果をoutAttrsに追加する。
00456     void Convert(
00457         typename TR::TOutAttributes& outAttrs,
00458         const typename TL::TInNode& parent,
00459         typename TL::TInIterator first, 
00460         typename TL::TInIterator last);
00461 
00462 private:
00463     typedef std::list<std::pair<typename TL::TPattern, typename TR::TPattern> >
00464         TRules;
00465 
00466     TRules rules;//ルール
00467 
00468     //値を変換。
00469     void ConvertValue(
00470         typename TR::TOutValue& outValue, 
00471         typename const TL::TInValue& inValue);
00472 
00473 };
00474 //*1 何故かTThis::を付けないと、VC7.1で関数の定義と宣言が一致しないと言われる。
00475 //---------------------------------------------------------------------------
00476 //キーと文字列の変換方法の定義。
00477 //変換元と変換先で、キー(Traits::TKey)と文字列(Traits::TValue)の型に互換性が無い
00478 //場合は、FIConvertationTraitsを特殊化して、適切なConvertKeyとConvertStringを
00479 //定義する必要がある。
00480 template <class TL, class TR>
00481 struct FIConvertationTraits
00482 {
00483     static typename TR::TKey ConvertKey(const typename TL::TKey& key){
00484         return key;
00485     }
00486     static typename TR::TString ConvertString(const typename TL::TString& str){
00487         return str;
00488     }
00489     
00490 };
00491 //---------------------------------------------------------------------------
00492 //各テンプレートクラスのメンバ関数の定義をinclude。
00493 #include "FITreeConverterImpl.h"
00494 //---------------------------------------------------------------------------
00495 #endif

Springheadに対してSun Apr 16 01:57:51 2006に生成されました。  doxygen 1.4.1