2016-10-24 28 views
1

私はantlr4 c++を使用しています。 私はParseTreeを持っていて、私は木構造を作り直そうとしています。 これまで私は訪問者my_Visitorと自分のノードオブジェクトを使用しています。parseTree traversal in antlr4

私の問題は、すべての子の訪問機能を呼び出すので、1つの子ツリーが横断され、次の子ツリーが訪問されたときに情報が失われているということです。 このようなツリーを想定:

A 
/\ 
B C 

IはvisitChildren(A)(B及びCのためのオーバーロードvisitExpression(ExpressionContext*)関数を使用して)呼び出すと、私は訪問配列は、B、Cであるという情報を抽出することができます。私は

antlrcpp::Any my_Visitor::my_visitChildren(tree::RuleNode* A){ 
    for(int i=0;i<A->children.size();i++){ 
     //create a new node in my own tree representation as child of A 
     visit(A->children[i]); 
    } 
} 

のようなものを必要とし、私のオーバーロードされたvisitExpression機能でmy_visitChildrenを呼び出すと思う木を再作成するには

A 
| 
B 
| 
C 

: このシーケンスも起因し得ます。ここ

問題はA->children[i]Treeで、visit(.)ParseTreeを必要としていることです。 何とかParseTreechildren[i]から作成することができますか、これを行うにはより良い方法がありますか?

私のオブジェクトにtree->parentのマップを使用して新しいノードを追加することも考えていますが、いくつかのノード(たとえばAST)を省略したい場合は最適ではありません。

+0

訪問者ではなくリスナーを使用する必要があるようです。 – cantSleepNow

+0

私は 'exitEveryRule(。)'を使って子供から出た情報を取得しますか?それはあなたが示唆していることですか?それは理にかなっているようです(私は確信しています)。 – Jonas

+0

ParseTreeAnnotatorなどと呼ばれるクラスがあります。これはスタックのようなものです。本の中のantlr4リファレンスの例を確認してください – cantSleepNow

答えて

2

ParseTreeTreeとの間の区別は、純粋に人工的であり、実際には実際には使用されない。ツリーノードの子は、実際にはすべてParseTreeのインスタンスです。 ParseTreeという基底クラスを構築することを除いて、実行時には使用されないツリークラスがいくつかあります。したがって、後で私はTreeSyntaxTreeおよびRuleNodeを削除し、それらをまとめてParseTreeクラスに入れました。

あなたの質問に答えるには、ツリーウォークのために子ノードをParseTreeに安全にキャストすることができます。