adt - 在 Rascal 中使用 "parent"标签注释 ADT/节点树

标签 adt rascal

我想创建一棵树(使用 NodeADT),其中每个节点都有一个指向其父节点的注释。下面是一个简单的链表数据结构的例子:

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
]

最佳答案

问题是 Rascal 数据是不可变的,因此您不能使用赋值更新任何内容。该赋值只会为您提供一个带有注释集的 cx 的新绑定(bind),但不会更改原始树。

要更改原始树,您可以对 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];
    }
}

关于adt - 在 Rascal 中使用 "parent"标签注释 ADT/节点树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19028623/

相关文章:

javascript - 新行作为空格和终止符

rascal - M3 的通用核心二元关系

map - 如何在 Rascal 中将值类型转换为 Map?

rascal - Java2OFG 找不到 eLib 中调用的方法?

Android/Eclipse - 是否可以使用一台设备模仿另一台设备?

Android SDK ADT 安装问题

android - 在 Eclipse 上集成 Realm.io

android - adt eclipse 包 02-07-2014 更新

android - 我可以删除谷歌播放服务语言文件吗?

rascal - 为什么这段 Rascal 模式匹配代码会占用这么多内存和时间?