3

すべてのノードがその親を指す注釈を持つ(Nodeまたはを使用して) ツリーを作成したいと考えています。ADT以下は、単純なリンク リスト データ構造の例です。

import util::Math;
import IO;
import Node;

anno LinkedList LinkedList@parent;
anno int LinkedList@something;

data LinkedList = item(int val, LinkedList next)
                | last(int val)
                ;

public LinkedList linkedList =  item(5,
                                    item(4,
                                        item(3,
                                            item(2,
                                                last(1)[@something=99]
                                            )[@something=99]
                                        )[@something=99]
                                    )[@something=99]
                                )[@something=99];

public LinkedList addParentAnnotations(LinkedList n) {
    return top-down visit (n) {
        case LinkedList x: {
            /* go through all children whose type is LinkedList */
            for (LinkedList cx <- getChildren(x), LinkedList ll := cx) {
                /* setting the annotation like this doesn't seem to work */
                cx@parent = x;
                // DOESN'T WORK EITHER: setAnnotation(cx, getAnnotations(cx) + ("parent": x));
            }
        }
    }
}

を実行addParentAnnotations(linkedList)すると、次の結果が得られます。

rascal>addParentAnnotations(linkedList);
LinkedList: item(
  5,
  item(
    4,
    item(
      3,
      item(
        2,
        last(1)[
          @something=99
        ])[
        @something=99
      ])[
      @something=99
    ])[
    @something=99
  ])[
  @something=99
]
4

1 に答える 1

3

問題は、Rascal のデータは不変であるため、代入を使用して何かを更新することはできません。割り当ては、アノテーション セットとの新しいバインディングを提供するだけですがcx、元のツリーは変更しません。

元のツリーを変更するには、=>case ステートメントに演算子を使用するか、insert次のステートメントを使用できます。

 case LinkedList x => x[@parent=...] // replace x by a new x that is annotated

また:

 case LinkedList x : {
    ...
    x@parent= ...;
    insert x; // replace original x by new x in tree
 }

その他のヒントとして、ライブラリには、ケースの本体から呼び出された場合に、現在アクセスしているノードの親のリストを生成するTraversal.rsc関数が呼び出されていることがわかります。getTraversalContext()

import Traversal;

visit (...) {
    case somePattern: {
        parents = getTraversalContext();
        parent = parents[1];
    }
}
于 2013-09-26T14:15:56.517 に答える