gpt4 book ai didi

attributes - 在 Rascal 中访问节点的 _all_ 下游注释

转载 作者:行者123 更新时间:2023-12-03 13:15:49 25 4
gpt4 key购买 nike

我读了 this question在尝试做类似的事情时。那里给出的答案并不能解决我的问题。

我想使用访问语句来确定每个子树的“质量”,因此对于每个节点,我想对所有后代的质量求和。例如,遇到此节点表达式的访问步骤中包含一个列表:

\anode([\bnode()[@mass=1], \bnode()[@mass=2]], \cnode()[@mass=5])

应该产生这个:
\anode([\bnode()[@mass=1], \bnode()[@mass=2]], \cnode()[@mass=5])[@mass=8]

所以我不只是想过滤掉非节点,而是实际遍历它们。在我的访问语句中包含列表案例不起作用(至少不是很明显),因为列表不能有注释。

是否有一种自然的方式将完整的注释信息向上传播?

最佳答案

如果具有容器子节点的节点数量不是很大,则第一个解决方案是精确且有用的:

x = \anode([\bnode()[@mass=1], \bnode()[@mass=2]], \cnode()[@mass=5]);

visit(x) {
case n:\anode(l) => n[@mass=(0 | it + e@mass | e <- l)]
}

(您可能还会在本地函数中抽象化 reducer 表达式)

第二种解决方案是从节点类型中抽象出来,以防你有很多这样的:
visit(x) {
case n:str _(l) => n[@mass=(0 | it + e@mass | e <- l)]
}

如果注释嵌套得更深(如列表等),并且您有许多不同类型的节点,则第三种解决方案最有效:
import Node;
int computeMass(list[value] x) {
mass = 0;
top-down-break visit(x) {
case node x : mass += (x@mass?) ? x@mass : 0;
}
return mass;
}

visit(x) {
case node n => n[@mass=computeMass(getChildren(n))]
}

我更喜欢第一个解决方案,因为它最精确。

请注意,我们将在不久的将来将注释功能替换为“关键字参数”;几乎相同的语义,不同的语法,例如 \cnode(mass=2)\code()[@mass=2] .使用新的关键字参数,您还可以为质量字段延迟计算默认值,如下所示:
data N() 
= anode(list[N] children, int mass=(0 | it + c.mass | c <- children))
| cnode(int mass=0)
;

anode([cnode(mass=1),cnode(mass=2)]).mass == 3

关于attributes - 在 Rascal 中访问节点的 _all_ 下游注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30901315/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com