不同的答案,更好或更差的不同方面。以下是一些:
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 规则声明的那样。词法子代将匹配lex,布局和文字与layouts 和lit 匹配。
没有所有的模式匹配:
int getChildrenCount4(Tree tree) {
return (0 | it + 1 | s <- tree.prod.symbols, isInteresting(s));
}
bool isInteresting(Symbol s) = s is sort || s is lex;