EN JP CN

例 6:カスタム関数の簡単な KAST 式をエミュレートする

例 6:カスタム関数の簡単な KAST 式をエミュレートする

次の読み取りやすい例で KAST ツリーノードをトラバースするには、ある型の KAST 式、特に逆ツリー構造のノードをトラバースするものをエミュレートできるラッパー関数を作成します。次のコードを考えてください。

 typedef struct
 {
   ktc_childId_t  edge;
   ktc_treeType_t type;
 } TRULE;
  
 ktc_tree_t traverse(ktc_tree_t node, TRULE* rules)
 {
   ktc_tree_t rc = node;
   TRULE*     ptr = rules;
  
   while( rc && ptr->edge )
   {
     rc = ktc_proceed(rc, ptr->edge);
     if( rc && !ktc_isTreeType(rc, ptr->type) )
       rc = 0;
     ptr++;
   }
   return rc;
 }


トラバースの呼び出しは、TRULE 構造の配列の宣言や 'traverse' 関数の呼び出しと同様に簡単です。'traverse' の結果は、トラバースの出力先またはゼロ (トラバースできなかった場合または検証の特殊化のひとつが一致しない場合) のいずれかです。

TRULE 配列の各エントリの場合、関数は、定義された子エッジを通してそれが進むことと、到達したノードのタイプが期待していたタイプと一致することを検証します。これは、配列の終わり (0 エッジのガード付き) まで続きます。

実行中の関数を確認するには、前例の要件 (// FuncDef / FuncBody / Stmt::CompoundStmt / Stmts[*]::ExprStmt) に戻り、式の検索を開始できるよう関数本体内のステートメントに移動します。通常、カスタム関数は FuncDef ノードで呼び出されるため、それを検索する必要はありませんが、そこから開始すると、次のルールを使用して関数内でステートメントのコレクションをトラバースできます。

 TRULE stmts[] = {
        { cid_FuncBody, tid_Any },
        { cid_Stmt, tid_CompoundStmt },
        { cid_Stmts, tid_Any },
        { 0, 0 }
 }
 ktc_tree_t statements = traverse(node, stmts);


コレクションおよび次元の検索ができるさまざまな KAST の機能は、ktc でネイティブには使用できません。 個々にコード化する必要があります。同等の "descendant::" 検索を実行する場合、できれば KAST 式でその部分を実行するのが最良です。こうすると、サブツリー検索アルゴリズムのコードを独自に作成する必要はありません。次の例では、カスタム関数のもっと複雑な検索パターンの記述を調べてみますが、一般的には、できれば KAST を複雑なノードのトラバーススキームに使用します。