2011-01-10 10 views
4

私はいくつかの小さな言語でいくつかの処理を行うためにQiとKarmaを使用してきました。ほとんどの文法はかなり小さい(20-40ルール)。私はautorulesをほとんど排他的に使用することができたので、私の解析木は完全にバリアント、構造体、およびstd :: vectorsで構成されています。
1))、何か(チー)を解析
2)構文解析ツリー(訪問者にマイナーな操作を行い、
3)出力の何か(カルマ):Boost :: Spirit :: Qi autorules - ASTデータ構造の繰り返しコピーを避ける

このセットアップは、一般的なケースのために素晴らしい作品。

しかし、大きなサブツリーを動かすなど、構文木に複雑な構造変更を加えたいと思ったらどうなるでしょうか。 ...

autorulesを使用して、S-exprのスタイルの論理式のための文法...

// Inside grammar class; rule names match struct names... 
pexpr %= pand | por | var | bconst; 
pand %= lit("(and ") >> (pexpr % lit(" ")) >> ")"; 
por %= lit("(or ") >> (pexpr % lit(" ")) >> ")"; 
pnot %= lit("(not ") >> pexpr >> ")"; 

...このようになりますツリー表現を解析するためにつながる次のおもちゃの例を考えてみましょう

 pand 
    /... \ 
    por  por 
/\ /\ 
var var var var 

(T:

struct var { 
    std::string name; 
}; 
struct bconst { 
    bool val; 
}; 

struct pand; 
struct por; 
struct pnot;        

typedef boost::variant<bconst, 
         var, 
         boost::recursive_wrapper<pand>, 
         boost::recursive_wrapper<por>, 
         boost::recursive_wrapper<pnot> > pexpr; 
struct pand { 
    std::vector<pexpr> operands;      
}; 

struct por { 
    std::vector<pexpr> operands;      
}; 

struct pnot { 
    pexpr victim; 
}; 

// Many Fusion Macros here 

私はこのようになります解析木を持っていると仮定彼は「pandのために類似した形状のより多くの子どもたち。」手段を省略記号)

を今、最終的な結果があるように私は、por各ノードを否定したいと:

 pand 
    /... \ 
    pnot  pnot 
    |  | 
    por  por 
/\ /\ 
var var var var 

直接的なアプローチだろうそれぞれporサブツリーに対して:
- 作成pnotノード
(構成はpor
pandノード
pnotノードとそのporサブツリーをコピー)に適切なベクトルスロットを再割り当てします。

また、別のベクターを作成してから、pandベクターの卸売りを交換(交換)して、2回目のコピーを削除することができました。

このすべては、既存のノードをコピーせずにpnotノードを挿入できるようにするポインタベースのツリー表現に比べて面倒なようです。私の質問:

オートホール準拠のデータ構造でコピーが多いツリー操作を避ける方法はありますか?私は弾丸を噛んで、ポインタベースのAST(例えば、http://boost-spirit.com/home/2010/03/11/s-expressions-and-variants/)を構築するために非オートルールを使用するだけですか?

答えて

3

recursive_variantは本質的にshared_ptrを囲むラッパーであるため、サブツリーをコピーすることは想定していたほど高価であってはなりません。私は信じて、最高のだけでなく、最も簡単な解決策でもあります。

+1

あなたの洞察をお寄せいただきありがとうございます。私は変種の実装にあまり注意を払っていなかった。 - 既存の2つのノードの間にノードを挿入すると、一定数のコピー操作が発生します(挿入の下にあるサブツリーのサイズとともに増加しません)。 - ほとんどのコピーはベクトルサイズ変更によって発生します これは、定型的な意味操作を必要とせずに、プール割り当てのポインタベースのASTノードに対してディレクタのサポートを持つことがうまくいくかもしれません。その設定の1つの素晴らしい特性は、安価な一意のハッシュとしてノードアドレスを使用できることです。 – phooji

関連する問題