我正在研究在AST中运行的scalac插件。现在,我在unit.body
的每个循环中使用a,这是从传递的Global
值中获得的。我面临的问题是,由于上述遍历的递归性质,我访问了每个Tree
及其子级,尽管我不想遍历后者,因为我正在使用模式匹配来匹配函数调用
例如,如果我要遍历以下语句:
x.do(arg1)(arg2)(arg3)
我将在遍历中得到以下内容:
1. x.do(arg1)(arg2)(arg3)
2. x.do(arg1)(arg2)
3. x.do(arg1)
4. x.do
5. x
6. do
7. arg1
8. arg2
9. arg3
在这里,我按照遍历的顺序缩进了Tree
对象。现在,如果我要使用Apply
case类与它们中的每一个进行匹配,我将得到1,2和3的匹配,而我实际上只想要1。我考虑使用上下文相关的解决方案(就像检查之前遍历的Tree
一样),但对于我的目的而言,一致性不够。我也不是在寻找使匹配更容易的特定方法,而是在一般方法上,但是我不能考虑这些孩子。
编写scalac插件时,是否可以使用更好的模式来匹配函数调用,还是可以使用更好的方法进行遍历,以免遇到递归问题?
答案 0 :(得分:0)
我自己找到了答案: 而不是使用直观的
for(tree <- treeObject)
,其中treeObject : Tree
您只需在每个children
对象中使用Tree
对象,然后执行以下操作
def func(treeObject : Tree) : Something = {
for(tree <- treeObject.children) {
if(/*your condition for further traversal*/)
func(treeObject : Tree) //RECURSE
else
someValue //do whatever and RETURN
}
}
使用这种方法,可以设置遍历的停止条件。假设您只想查看每个方法调用。可以匹配使用Apply
case类的方法调用。现在,您只需检查您当前的tree
是否与该模式匹配即可。如果这样做,您将对其进行工作并返回。如果没有使用递归进一步遍历Tree
,则可以进一步“向下”获得可能的方法调用。