首页 > 解决方案 > 获取树节点的子节点数

问题描述

Node的文档仅提及以下方法:

Equal, GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual, NotEqual, Slice,Subscription

它确实提到了如何使用索引访问子Subscription节点,但是我怎样才能找出子节点的数量必须遍历它们?

这是我的用例:

Exp parsed = parse(#Exp, "2+(4+3)*48");
println("the number of root children is: " + size(parsed));

但它会产生错误,因为它size()似乎只适用于List.

标签: rascal

解决方案


不同的答案,更好或更坏的不同方面。这里有几个:

import ParseTree;

int getChildrenCount1(Tree parsed) {
   return (0 | it + 1 | _ <- parsed.args);
}

getChildrenCount1遍历解析树节点的原始子节点。这包括空格和注释节点 ( layout) 和关键字 ( literals)。您可能希望过滤这些,或按除法补偿。

另一方面,这似乎有点间接。我们也可以直接询问孩子列表的长度:

import List;
import ParseTree;

int getChildrenCount2(Tree parsed) {
   return size(parsed.args) / 2 + 1; // here we divide by two assuming every other node is a layout node
}

还有元数据的方式。每个解析树节点都有一个直接在那里可以查询和探索的生产的声明性描述:

import ParseTree;
import List;

// immediately match on the meta-structure of a parse node:
int getChildrenCount3(appl(Production prod, list[Tree] args)) {
    return size(prod.symbols);
}

这个符号的长度应该和 args 的长度一样。

// To filter for "meaningful" children in a declarative way:
int getChildrenCount4(appl(prod(_, list[Symbol] symbols, _), list[Tree] args)) {
    return (0 | it + 1 | sort(_) <- symbols);
}

使用规则sort声明的上下文无关非终结符的过滤器。syntax词法子级将与 and 匹配布局lex和文字。layoutslit

没有所有的模式匹配:

int getChildrenCount4(Tree tree) {
    return (0 | it + 1 | s <- tree.prod.symbols, isInteresting(s));
}

bool isInteresting(Symbol s) = s is sort || s is lex;

推荐阅读